web-dev-qa-db-ja.com

TomcatのJAX-RS(ジャージー)でHTTP 404 JSON / XML応答を返す方法

私は次のコードを持っています:

@Path("/users/{id}")
public class UserResource {

    @Autowired
    private UserDao userDao;

    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public User getUser(@PathParam("id") int id) {
        User user = userDao.getUserById(id);
        if (user == null) {
            throw new NotFoundException();
        }
        return user;
    }

/users/1234のような存在しないユーザーに "Accept: application/json"を指定してリクエストすると、このコードはHTTP 404レスポンスを返しますが、Content-Typeを返します。 text/htmlおよびhtmlの本文メッセージに設定します。注釈@Producesは無視されます。

コードの問題ですか、構成の問題ですか?

31
IJR

キャッチされない例外は、定義済み(デフォルト)を使用してjax-rsランタイムによって処理されるため、@Producesアノテーションは無視されますExceptionMapper特定の例外の場合に返されるメッセージをカスタマイズする場合、独自のExceptionMapperで処理します。あなたの場合、NotFoundException例外を処理し、要求された応答のタイプの「accept」ヘッダーを照会する必要があります。

@Provider
public class NotFoundExceptionHandler implements ExceptionMapper<NotFoundException>{

    @Context
    private HttpHeaders headers;

    public Response toResponse(NotFoundException ex){
        return Response.status(404).entity(yourMessage).type( getAcceptType()).build();
    }

    private String getAcceptType(){
         List<MediaType> accepts = headers.getAcceptableMediaTypes();
         if (accepts!=null && accepts.size() > 0) {
             //choose one
         }else {
             //return a default one like Application/json
         }
    }
}
32
Svetlin Zarev

Responseリターンを使用できます。以下の例:

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("id") Long id) {
    ExampleEntity exampleEntity = getExampleEntityById(id);

    if (exampleEntity != null) {
        return Response.ok(exampleEntity).build();
    }

    return Response.status(Status.NOT_FOUND).build();
}
15
Tiago

次の形式で物事を渡すことが予想されるため、サーバーから404が返される

/users/{id}

しかし、あなたはそれを渡している

/users/user/{id}

どのリソースがまったく存在しない

/users/1234としてリソースにアクセスしてみてください

編集:

のようなクラスを作成する

class RestResponse<T>{
private String status;
private String message;
private List<T> objectList;
//gettrs and setters
}

Userに対する応答が必要な場合は、次のように作成できます

RestResponse<User> resp = new RestResponse<User>();
resp.setStatus("400");
resp.setMessage("User does not exist");

残りのメソッドの署名は次のようになります

public RestResponse<User> getUser(@PathParam("id") int id)

応答が成功した場合、次のような設定ができます

RestResponse<User> resp = new RestResponse<User>();
List<User> userList = new ArrayList<User>();
userList.add(user);//the user object you want to return
resp.setStatus("200");
resp.setMessage("User exist");
resp.setObjectList(userList);
0
dev2d