如何在 Tomcat 上的 JAX-RS (Jersey) 中返回 HTTP 404 JSON/XML 响应?
Posted
技术标签:
【中文标题】如何在 Tomcat 上的 JAX-RS (Jersey) 中返回 HTTP 404 JSON/XML 响应?【英文标题】:How I return HTTP 404 JSON/XML response in JAX-RS (Jersey) on Tomcat? 【发布时间】:2014-07-14 12:58:17 【问题描述】:我有以下代码:
@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;
如果我使用“Accept: application/json
”请求不存在的用户(例如 /users/1234
),则此代码会像预期的那样返回 HTTP 404
响应,但返回的 Content-Type
设置为 text/html
和一个html的正文消息。注释@Produces
被忽略。
是代码问题还是配置问题?
【问题讨论】:
【参考方案1】:您的 @Produces
注释将被忽略,因为 jax-rs 运行时使用预定义(默认)ExceptionMapper
处理未捕获的异常987654323@处理它。在您的情况下,您需要一个处理 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
【讨论】:
我测试过了。我继续抛出 NotFoundException,但现在使用 ExceptionMapper 将该异常映射到设置状态代码和媒体类型。有用!在此之前,我尝试返回等效响应而不是抛出 NotFoundException,但我得到相同的结果,即 text/html 404 响应。这种行为是因为如果我的应用程序抛出 NotFoundException 默认(隐式)ExceptionMapper 进入并覆盖我返回到 html 响应的响应?谢谢! 尝试不同的解决方案后,这是最好的和正确的解决方案。映射 NotFoundException 不是必须的。只需使用 Exception 并做你需要的事情 @Provider 很重要【参考方案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();
【讨论】:
【参考方案3】:您的服务器返回 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);
【讨论】:
URI 请求已更新,我输入 URI 时出错。正确的 URI 是 users/1234 以在 html 中获得 404 响应,而不是在 JSON 中。我的问题不是响应代码,而是响应格式(内容类型)。 从产品中删除 MediaType.APPLICATION_XML 并尝试,同时确保在用户不存在的情况下提供正确的消息。通常我们会创建一个休息响应,其中将包含用户请求的状态和消息,当有人尝试访问资源时,我们会返回与响应相同的响应 我试图从注释 @Produces 中删除 MediaType.APPLICATION_XML,我得到了相同的结果,一个带有 text/html Content-Type 的 404 响应。这就像 Tomcat 被覆盖的内容类型和正文消息...... 正如我在上面的评论中提到的,如果用户不存在,您需要传递一个包含状态和消息的类的对象,您需要明确设置状态将编辑 ans 也许我会混合使用两种方法(VD' 和 Svetlin Zarev),使用带有实体的 ExceptionMapper,该实体不仅是字符串消息,而且是具有状态码、消息等属性的对象。谢谢!以上是关于如何在 Tomcat 上的 JAX-RS (Jersey) 中返回 HTTP 404 JSON/XML 响应?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jax-RS(Jersey) 在 Tomcat7 上运行应用程序 Hibernate 5.x、Jpa 2.1、Java EE7(javaee-api 7.0)
如何使用 JAX-RS 异常上的自定义消息设置 40X 错误?