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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23858488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:35:44  来源:igfitidea点击:

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

javaresttomcathttp-status-code-404jersey-2.0

提问by IJR

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 404response like one would expect, but returns Content-Typesets to text/htmland a body message of html. Annotation @Producesis ignored.

如果我请求一个不存在的用户,例如/users/1234带有“ Accept: application/json”的用户,则此代码将返回一个符合HTTP 404预期的响应,但返回Content-Type设置为text/html和 html 的正文消息。注释@Produces被忽略。

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

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

采纳答案by Svetlin Zarev

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

@Produces因未捕获的异常是由JAX-RS处理注释被忽略使用预定义(默认)运行时ExceptionMapper如果您希望自定义返回的消息在一个特定的异常的情况下,你可以创建自己ExceptionMapper来处理它。在您的情况下,您需要一个来处理NotFoundException异常并查询请求类型的响应的“接受”标头:

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

回答by dev2d

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 Useryou 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

你的rest方法的签名如下

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

回答by Tiago

You can use the Response return. Example below:

您可以使用 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();
}