泽西岛2.3拦截器示例不起作用

时间:2013-11-01 12:51:49

标签: rest jersey jersey-2.0

我正在尝试使用Tomcat 7获取Jersey 2.3 Interceptor示例found here并使用名称绑定工作。我按照链接中显示的示例创建了以下内容......

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress{}

@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
  final OuputStream outputStream .....  
  ..some logging added here..
}

@Path("helloword")
public class HelloWorldResource {

  @GET
  @Path("to-much-data")
  @Compress
  public String getVeryLongString(){
    String str = "a very ...
    ..... large string";
    return str;
  }
}

我没有在web.xml中添加任何额外的内容来注册Interceptor,因为用户指南文档中没有讨论过这个问题。我注意到这是泽西岛早期版本中使用的方法。

我测试了压缩拦截器是否使用从jersey客户端api构建的客户端。我确保在发送请求之前将HttpHeaders.ACCEPT_ENCODING, "gzip"标头添加到Invocation.Builder。我还添加了对GZIPWriterInterceptor的记录。当我测试以查看响应是否已压缩时,它以纯文本形式返回(在响应头中设置了Content-Type - text/plain)并且我在日志中看不到GZIPWriterInterceptor消息。

有没有人知道我做错了什么或者我还能尝试什么?

编辑 - 我更新了我的web.xml以尝试注册GZIPWriterInterceptor类。

......
.
<servlet>
  <servlet-name>Jersey Test Servlet</servlet-name>
  <servlet-value>org.glassfish.jersey.servlet.ServletContainer</servlet-value>
  <init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>com.test.jersey</param-value>
  </init-param>
  <init-param>
    <param-name>com.ws.rs.ext.WriterInterceptor</param-name>
    <param-value>com.test.jersey.GZIPWriterInterceptor</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
.
.......

这没效果。我是否使用WriterInterceptor的参数名称注册GZIPWriterInterceptor?

UPDATE - 我设法通过扩展javax.ws.rs.core.Application并注册我需要的每个类(HelloWorldResource.class,GZIPWriterInterceptor.class,Compress)来使压缩工作。如部署不可知应用程序模型found here中所述。

我在web.xml中注册了我的Application类......

<display-name>JerseyInterceptorTest2</display-name>
  <servlet>
    <servlet-name>Jersey Rest Test</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.jersey.test.MyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
     <servlet-name>Jersey Rest Test</servlet-name>
     <url-pattern>/*</url-pattern>
  </servlet-mapping>

根据Example 4.2,我尝试通过扩展ResourceConfig来尝试注册我的软件包失败。并通过web.xml中的早期方法

<init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>com.test.jersey</param-value>
</init-param>

目前还不清楚为什么包注册不起作用。

4 个答案:

答案 0 :(得分:5)

您需要做两件事:

  1. 从提供的代码段开始,您的WriterInterceptor似乎没有使用@Compress注释进行注释。请这样做,以确保您的提供商和资源方法匹配在一起。
  2. 您需要在JAX-RS Application课程或web.xml中注册提供者。文档可能有点含糊不清(我们会解决这个问题)。

答案 1 :(得分:4)

拦截器类也必须使用@Provider进行注释,如下所示:

@Provider
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor { ...

然后在包扫描中将其拾取。

文档here未明确指定。

答案 2 :(得分:0)

确保所有类(Compress,GZIPWriterInterceptor,HelloWorldResource)都在web.xml中参数“jersey.config.server.provider.packages”指定的同一个包下。

我觉得@NameBinding无法正常工作,我发现我把Compress放到了另一个包中。

答案 3 :(得分:0)

  1. 不要忘记将@Provider注释放在编写器类
  2. 之上
  3. 将Writer,Compress和资源放在同一个包中
  4. (最重要):在应用程序类上注册类:
  5.         @ApplicationPath("myrest")
            public class MyRestApplication extends Application{
    
            @Override
            public Set<Object> getSingletons() {
    
                Set<Object> singletons = new HashSet<Object>();
                singletons.add(new AuthorResource());
                singletons.add(new GZipWriterInterceptor());
                singletons.add(new EncodingFilter());
                singletons.add(new GZipEncoder());
                return singletons;
              } 
            }