防止Tomcat在HTTP错误状态4xx或5xx上干扰Jersey / JAX-RS 2响应主体

时间:2014-01-15 10:15:43

标签: java rest tomcat7 jax-rs jersey-2.0

我有以下用于REST API的堆栈

  • Jersey 2 / JAX RS 2.0
  • Tomcat 7.0.47
  • Jackson 2

我的目标是在发生错误时拥有自定义响应正文。我希望能够向客户端发送一个解释是什么问题,以便于调试。

首先我尝试使用@Context HttpServletResponse并在那里设置http状态代码,但是被泽西忽略了(这是正常的行为,但这超出了我的理解)

然后我尝试像这样使用WebApplicationException

@GET
@Path("/myapi")
public BaseResponse getSomething() {
   BaseResponse b = new BaseResponse();
   if(error) {
      b.setStatusDescription("reason for error");
      throw new WebApplicationException(Response.status(Response.Status.CONFLICT).entity(b).build());
   }
   //add content to BaseReponse
   return b
}

但Tomcat给我的回报是这样的:

<html>
    <head>
        <title>Apache Tomcat/7.0.47 - Error report</title>
        <style>
            <!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22p

标准的Tomcat html输出由我想要返回的响应主体的上下文长度限制(.entity(b) - b的长度)。所以它被认可,但Tomcat只是用自己的错误页面覆盖它。

作为旁注,我也尝试以相同的结果返回响应:

return Response.status(Response.Status.CONFLICT).entity(b).build()

那么我该怎么告诉Tomcat让我一个人留下来让我自己的回答呢?

2 个答案:

答案 0 :(得分:7)

只需在ResourceConfig类的配置中添加以下代码。

property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true");

请参阅jersey.config.server.response.setStatusOverSendError

答案 1 :(得分:0)

问题在于我使用的是ehcache的GzipServlet,它似乎不适用于球衣。在多个阶段,响应包装器抛出了异常。

这是ehcache的依赖:

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-web</artifactId>
            <version>2.0.4</version>
        </dependency>

web.xml中有问题的servlet定义

<filter>
        <filter-name>GzipFilter</filter-name>
        <filter-class>net.sf.ehcache.constructs.web.filter.GzipFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>GzipFilter</filter-name>
        <url-pattern>/rest/*</url-pattern>
    </filter-mapping>

作为替代方案我现在使用Jetty Servlet:http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/servlets/GzipFilter.html

<dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlets</artifactId>
            <version>8.1.0.RC5</version>
        </dependency>

的web.xml

<filter>
  <filter-name>GzipFilter</filter-name>
  <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
  <init-param>
    <param-name>mimeTypes</param-name>
    <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>GzipFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

作为免责声明:是的我知道我可以在tomcat配置中激活gzip,但我正在编写一个必须能够使用和不使用gzip的端点的测试服务器。