it-roy-ru.com

Как мне вернуть HTTP 404 JSON/XML-ответ в JAX-RS (Джерси) на Tomcat?

У меня есть следующий код:

@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 игнорируется.

Это проблема кода или проблема конфигурации? 

30
IJR

Ваша аннотация @Produces игнорируется, поскольку необработанные исключения обрабатываются средой выполнения jax-rs с использованием предопределенной (по умолчанию) 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
         }
    }
}
30
Svetlin Zarev

Вы можете использовать ответ ответ. Пример ниже:

@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();
}
16
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
VD'