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

问题描述 投票:0回答:4

我有以下代码:

@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
被忽略。

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

java rest tomcat http-status-code-404 jersey-2.0
4个回答
38
投票

您的

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

18
投票

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

0
投票

您的服务器返回 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
投票

就我而言,问题是混合使用 jakarta 和 javax 包。我删除了 jakarta 并仅使用 javax 软件包,问题就消失了。

© www.soinside.com 2019 - 2024. All rights reserved.