Java 忽略带有Jersey';例外情况 @Provider 公共类Jersey ExceptionMapper实现ExceptionMapper{ @凌驾 公众响应(运动衫例外运动衫例外){ 返回Response.status(jerseyException.getErrorCode())。 实体(jerseyException.getJsonResponseObj()。 类型(MediaType.APPLICATION_JSON)。 build(); } }

Java 忽略带有Jersey';例外情况 @Provider 公共类Jersey ExceptionMapper实现ExceptionMapper{ @凌驾 公众响应(运动衫例外运动衫例外){ 返回Response.status(jerseyException.getErrorCode())。 实体(jerseyException.getJsonResponseObj()。 类型(MediaType.APPLICATION_JSON)。 build(); } },java,jersey,jax-rs,Java,Jersey,Jax Rs,当您在web.xml中使用组件时,上面的代码会产生不需要的结果。例如,如果myResponse.status设置为400,并且myerror page组件将定义为400,则web服务器将请求重定向到web.xml中定义的位置 这显然不是我想要的REST请求。我读了另一篇关于StackOverflow的帖子,上面说请求被转移到错误页面的原因是HttpServletResponse.sendError(400)被设置了。那篇帖子说如果你设置了HttpServletResponse.setStatus

当您在
web.xml
中使用
组件时,上面的代码会产生不需要的结果。例如,如果my
Response.status
设置为400,并且my
error page
组件将
定义为400,则web服务器将请求重定向到
web.xml
中定义的位置

这显然不是我想要的REST请求。我读了另一篇关于StackOverflow的帖子,上面说请求被转移到
错误页面的原因是
HttpServletResponse.sendError(400)
被设置了。那篇帖子说如果你设置了
HttpServletResponse.setStatus(400)
,那么
错误页面将被忽略

如果这是真的,我不认为这有什么帮助,因为我没有实现Jersey代码。我看到的选项是调查响应类源代码,并可能重新实现status方法或其他代码。这里有一个简单的选择还是我遗漏了什么


本质上,我的问题是:考虑到我正在使用Jersey进行REST,并且在
web.xml
中使用了错误页面,我如何在仅忽略Jersey代码的
错误页面的同时使用上述代码?导致HTTP错误的任何其他代码都应转到
错误页面
。或者是否有另一种解决方案不涉及
错误页
,但其工作原理与我想要的完全相同?

我可以重现该问题,但前提是我将
null
作为实体内容传递

示例:

@Provider
public class JerseyExceptionMapper implements ExceptionMapper<JerseyException> {


    @Override
    public Response toResponse(JerseyException jerseyException) {
        return Response.status(jerseyException.getErrorCode()).
                entity(jerseyException.getJsonResponseObj()).
                type(MediaType.APPLICATION_JSON).
                build();
    }

}
甚至

return Response.status(400)
        .entity(null)
        .type(MediaType.APPLICATION_JSON)
        .build();
两者都将导致重定向到为HTTP状态代码400设置的错误页面,因为如果未指定消息内容,容器将使用该方法

但如果你这样做:

return Response.status(400)
        .type(MediaType.APPLICATION_JSON)
        .build();
或者这个:

return Response.status(400)
        .entity("An error occured.")
        .type(MediaType.APPLICATION_JSON)
        .build();
容器/jersey将只使用该方法,而不会重定向到错误页面。如文件所述:

此方法用于在没有返回状态代码时设置返回状态代码 错误(例如,对于SC_OK或SC_MOVED_暂时状态 代码)

如果此方法用于设置错误代码,则容器的 错误页面机制将不会被触发。如果出现错误,请执行以下操作: 调用方希望调用web中定义的错误页 应用程序,然后必须使用sendError(int,java.lang.String) 相反

所以在您的例子中,问题似乎是
jerseyException.getJsonResponseObj()
返回
null
。您应该实现空检查以避免这种情况

Jersey 1.x中有一个bug描述了这个问题,它在没有修复的情况下关闭了,但是建议使用一个空的实体字符串作为解决方法
Jersey 2.x也有一个类似的漏洞:

另请参见:

@Provider
public class JerseyExceptionMapper implements ExceptionMapper<JerseyException> {


    @Override
    public Response toResponse(JerseyException jerseyException) {
        return Response.status(jerseyException.getErrorCode()).
                entity(jerseyException.getJsonResponseObj()).
                type(MediaType.APPLICATION_JSON).
                build();
    }

}

您使用的是哪个servlet容器?这可能与我无法重现此问题有关(glassfish 4.2.13)。1) 什么是
JerseyException
?2) 你检查过地图绘制程序是否被调用了吗?3) 为了实现这一点,我只需创建一个
JerseyException
类extend
WebApplicationException
,并从资源方法中抛出它。4) 如果3。你能不能提供更多的信息来重现这个,比如环境,泽西版本,服务器,抛出异常的地方。我会给你奖金,因为你提供了很好的信息。但是,我认为在我的案例中发生的(您无法知道)是entity()方法引发的异常,因为没有找到MessageBodyWriter。该异常必须已导致调用errorCode方法。一旦我在我的项目中包括genson JAR,我就不会再有这些错误了。这正是我所需要的。泽西岛的官方文档中未提及此错误处理。