简体   繁体   English

我如何在Tomcat上的JAX-RS(Jersey)中返回HTTP 404 JSON / XML响应?

[英]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. 如果我通过“ Accept: application/json ”请求不存在的用户(例如/users/1234 ,则此代码返回HTTP 404响应,就像人们期望的那样,但将Content-Type集返回到text/html和html的正文消息。 Annotation @Produces is ignored. 注释@Produces被忽略。

Is it a problem of code or a problem of configuration? 这是代码问题还是配置问题?

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. 您的@Produces注释被忽略,因为jax-rs运行时使用预定义的(默认) ExceptionMapper处理未捕获的ExceptionMapper如果要在特定异常的情况下自定义返回的消息,您可以创建自己的ExceptionMapper来处理它。 In your case you need one to handle the NotFoundException exception and query the "accept" header for the requested type of the response: 在您的情况下,您需要一个处理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
         }
    }
}

You can use the Response return. 您可以使用响应返回。 Example below: 示例如下:

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

that 404 is returned by your server as it is expected that you will pass things in following form 您的服务器返回404,因为您希望以下列形式传递内容

/users/{id}

but you are passing it as 但是你把它传递给了

/users/user/{id}

which resource is not existing at all 哪个资源根本不存在

try accessing resource as /users/1234 尝试访问资源/users/1234

EDIT: 编辑:

create a class like 创建一个类似的

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

now in case you want response for User you can create it as following 现在,如果您想要响应User您可以按如下方式创建它

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

and signature of your rest method would be like following 和你的休息方法的签名将如下

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

while in case successful response you can set things like 如果成功响应你可以设置像

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM