名称绑定
名称绑定是一种概念,它允许向 JAX-RS 运行时说明仅针对特定资源方法执行特定过滤器或拦截器。当过滤器或拦截器仅限于特定的资源方法时,我们说它是名称绑定的。没有这种限制的过滤器和拦截器称为全局。
定义名称绑定注释
可以使用 @NameBinding
注释将过滤器或拦截器分配给资源方法。此批注用作应用于提供者和资源方法的其他用户实现的批注的元标注。请参阅以下示例:
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress {}
上面的示例定义了一个新的 @Compress
注释,它是一个名称绑定注释,因为它用 @NameBinding
注释。@Compress
注释可用于将过滤器和拦截器绑定到端点。
将过滤器或拦截器绑定到端点
假设你有一个执行 GZIP 压缩的拦截器,并且你希望将此类拦截器绑定到资源方法。为此,请注释资源方法和拦截器,如下所示:
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream));
context.proceed();
}
}
@Path("helloworld")
public class HelloWorldResource {
@GET
@Produces("text/plain")
public String getHello() {
return "Hello World!";
}
@GET
@Path("too-much-data")
@Compress
public String getVeryLongString() {
String str = ... // very long string
return str;
}
}
@Compress
应用于资源方法 getVeryLongString()
和拦截器 GZIPWriterInterceptor
。只有在执行具有此类注释的任何资源方法时,才会执行拦截器。
在上面的例子中,拦截器只能用于 getVeryLongString()
方法。对于方法 getHello()
,不会执行拦截器。在这个例子中,原因可能很清楚。我们想只压缩长数据,我们不需要压缩 Hello World!
的短响应。
名称绑定可以应用于资源类。在示例中,HelloWorldResource
将使用 @Compress
进行注释。这意味着在这种情况下所有资源方法都将使用压缩。
请注意,全局过滤器始终执行,因此即使对于具有任何名称绑定注释的资源方法也是如此。