我创建了一个Jersey过滤器,我需要将其分配给某些资源(不是全部)。因此,我正在使用动态绑定来实现这一点。
public class MyDynamicFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
Path resourcePath = resourceInfo.getResourceClass().getAnnotation(Path.class);
if (resourcePath != null && resourcePath.value().contains("/v2/"))
{
featureContext.register(MyFilter.class);
}
}
}
因此,我希望将此过滤器应用于路径中包含特定字符串的那些资源中的所有方法。其中一些资源使用子资源定位符来定义子资源。例如,
@Path("/v2/resource_path")
@Consumes({ ... })
@Produces({ ... })
class MyResource
{
@Path("/subresource_path")
public MySubResource getSubResource(@Context ResourceContext rc)
{
return rc.getResource(MySubResource.class);
}
}
即使Jersey文档声称
将为应用程序中定义的每个资源方法执行一次configure方法。
上面显示的configure
方法MyDynamicFeature
根本不会被classgetSubResource
方法调用MyResource
。但是,确实会为类中的所有其他方法调用该函数MyResource
(在示例中已将其省略)。
有没有办法使此工作适用于子资源?我也需要应用过滤器MySubResource
。
我们使用泽西岛2.21
看看这个问题。我不确定目前是否可行。如果在功能中添加一些日志记录来记录方法和类,您将看到子资源方法永远不会被遍历。正如Marek在本期杂志中所解释的那样,这是因为要处理此问题,需要调用子资源定位器方法,而从未如此。
唯一的解决方法是改为使用Name Binding
。我已经对此进行了测试,并且可以正常工作(见下文)。这个想法是做一个自定义的注释,并注释您想要过滤的过滤器,资源类和子资源类。例如
@NameBinding
@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeAnno {}
@SomeAnno
public class Filter implements ContainerRequestFilter {}
@SomeAnno
@Path("v2")
public class V2Resource {
@Path("sub")
public V2SubResource get() {
return new V2SubResource();
}
@SomeAnno
public static class V2SubResource {
@GET
public String get() { return "get"; }
}
}
上面会绑定所有的资源方法V2Resource
以及V2SubResource
。
以下是使用Jersey测试框架的完整示例。像其他任何JUnit测试一样运行它
更新:请注意,在以下测试中,对于当前(2.26)版本的Jersey,由于过滤器中返回了1000状态代码,因此版本2资源的测试挂起。我猜泽西不喜欢这样。要解决此问题,只需将过滤器中的状态码更改为500,并相应地修复测试断言,以测试500状态码。
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.logging.Logger;
import javax.ws.rs.GET;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Path;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
/**
* Stack Overflow question http://stackoverflow.com/q/36878817/2587435
*
* Run this like any other JUnit test. Only one required test dependency
*
* <dependency>
* <groupId>org.glassfish.jersey.test-framework.providers</groupId>
* <artifactId>jersey-test-framework-provider-inmemory</artifactId>
* <version>${jersey2.version}</version>
* </dependency>
*
* @author Paul Samsotha
*/
public class DynamicSubresourceTest extends JerseyTest {
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public static @interface Status1000 {}
@Provider
@Status1000
public static class Status1000Filter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext context) throws IOException {
context.abortWith(Response.status(500).build());
}
}
@Path("v1")
public static class V1Resource {
@GET
public String get() {
return "v1";
}
@Path("sub")
public V1SubResource getSub() {
return new V1SubResource();
}
public static class V1SubResource {
@GET
public String get() {
return "v1subresource";
}
}
}
@Path("v2")
@Status1000
public static class V2Resource {
@GET
public String get() {
return "v2";
}
@Path("sub")
public V2SubResource getSub() {
return new V2SubResource();
}
@Status1000
public static class V2SubResource {
@GET
public String get() {
return "v2subresource";
}
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(V1Resource.class, V2Resource.class)
.property(ServerProperties.WADL_FEATURE_DISABLE, true)
.register(Status1000Filter.class)
.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}
@Test
public void should_return_1000_for_v2_resource_method() {
final Response response = target("v2").request().get();
assertThat(response.getStatus(), is(500));
}
@Test
public void should_return_1000_for_v2_subresource_locator() {
final Response response = target("v2/sub").request().get();
assertThat(response.getStatus(), is(500));
}
@Test
public void should_return_data_for_v1_resource_method() {
final Response response = target("v1").request().get();
assertThat(response.getStatus(), is(200));
assertThat(response.readEntity(String.class), is("v1"));
}
@Test
public void should_return_data_for_v1_subresource_locator() {
final Response response = target("v1/sub").request().get();
assertThat(response.getStatus(), is(200));
assertThat(response.readEntity(String.class), is("v1subresource"));
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句