javaresttomcathttp-status-code-404jersey-2.0

How I return HTTP 404 JSON/XML response in JAX-RS (Jersey) on Tomcat?


I have the following code:

@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;
    }

If I request for a user that doesn't exists, like /users/1234, with "Accept: application/json", this code returns an HTTP 404 response like one would expect, but returns Content-Type sets to text/html and a body message of html. Annotation @Produces is ignored.

Is it a problem of code or a problem of configuration?


Solution

  • Your @Produces annotation is ignored because uncaught exceptions are processed by the jax-rs runtime using a predefined (default) ExceptionMapper If you want to customize the returned message in case of a specific exception you can create your own ExceptionMapper to handle it. In your case you need one to handle the NotFoundException exception and query the "accept" header for the requested type of the response:

    @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
             }
        }
    }