与泽西的ExceptionMapper页面
@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();
}
}
当您在web.xml
使用<error-page>
组件时,上面的代码会产生不想要的结果。 例如,如果我的Response.status
设置为400,并且我的error-page
组件将<error-code>
定义为400,那么Web服务器会将请求重定向到web.xml
定义的位置。
这显然不是我想要的REST请求。 我读了StackOverflow上的另一篇文章,说一个请求被转移到error-page
的原因是因为HttpServletResponse.sendError(400)
被设置。 那篇文章说如果你设置HttpServletResponse.setStatus(400)
, error-page
将被忽略。
如果这是真的,我没有看到它有什么帮助,因为我没有实现泽西岛代码。 我看到的选项是调查Response类源代码,并可能重新实现状态方法或其他泽西岛代码。 这里有一个简单的选项或我错过了什么吗?
基本上,我的问题是:鉴于我正在使用Jersey for REST,并且在我的web.xml
使用了错误页面,我怎样才能使用上面的代码,而忽略Jersey代码的error-page
? 任何其他导致HTTP错误的代码都应该进入error-page
。 还是有另一种解决方案不涉及error-page
但会与我想要的完全相同?
我可以重现这个问题,但只有当我传递null
作为实体内容。
例:
return Response.status(400)
.entity(null)
.type(MediaType.APPLICATION_JSON)
.build();
甚至
return Response.status(400)
.type(MediaType.APPLICATION_JSON)
.build();
两者都会导致重定向到为HTTP状态代码400设置的错误页面,因为如果没有指定消息内容,容器将使用sendError()方法。
但是,如果你这样做:
return Response.status(400)
.entity("An error occured.")
.type(MediaType.APPLICATION_JSON)
.build();
或这个:
return Response.status(400)
.entity("")
.type(MediaType.APPLICATION_JSON)
.build();
容器/球衣只会使用setStatus()方法,不会重定向到错误页面。 正如文档中所述:
此方法用于在没有错误时设置返回状态码(例如,对于SC_OK或SC_MOVED_TEMPORARILY状态码)。
如果使用此方法设置错误代码,则不会触发容器的错误页面机制。 如果出现错误并且调用者希望调用Web应用程序中定义的错误页面,则必须使用sendError(int,java.lang.String)。
所以在你的情况下,问题似乎是jerseyException.getJsonResponseObj()
返回null
。 您应该实施一个空检查来避免这种情况。
Jersey 1.x有一个错误JERSEY-1557,它描述了这个问题,它没有修复就关闭了,但是建议使用空实体字符串作为解决方法。
Jersey 2.x也有类似的bug:JERSEY-2673
也可以看看:
上一篇: page with Jersey's ExceptionMapper
下一篇: How to return http status code for exceptions in rest services