我如何在 Tomcat 上的 JAX-RS (Jersey) 中返回 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;
    }

如果我请求一个不存在的用户,比如 带有“”,则此代码将返回一个响应,就像人们期望的那样,但返回sets to和html的正文消息。注释将被忽略。/users/1234Accept: application/jsonHTTP 404Content-Typetext/html@Produces

是代码问题还是配置问题?


答案 1

您的注释将被忽略,因为未捕获的异常由 jax-rs 运行时使用预定义的(默认)进行处理 如果要在发生特定异常时自定义返回的消息,则可以创建自己的消息来处理它。在你的情况下,你需要一个来处理异常,并查询“accept”标头以获取请求的响应类型:@ProducesExceptionMapperExceptionMapperNotFoundException

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

答案 2

可以使用响应返回。示例如下:

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