在Jersey中过滤器的动态绑定不适用于子资源

简·多伊

我创建了一个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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Jersey中过滤器的动态绑定不适用于子资源

来自分类Dev

Angular JS Order By过滤器不适用于动态谓词

来自分类Dev

angularJS ng-repeat过滤器不适用于动态字段

来自分类Dev

表格过滤器不适用于退格键

来自分类Dev

javascript过滤器方法不适用于getElementsByName

来自分类Dev

Xfade过滤器不适用于ffmpeg

来自分类Dev

HBase LESS过滤器不适用于字节

来自分类Dev

列过滤器不适用于行分组

来自分类Dev

数组过滤器不适用于状态

来自分类Dev

C中的过滤器程序不适用于更复杂的图像

来自分类Dev

意图过滤器不适用于Android中的ActivityTestRule

来自分类Dev

表中的过滤器 (ngRepeat) 不适用于所有列

来自分类Dev

boto3 中的 describe_snapshots 过滤器不适用于“描述”字段

来自分类Dev

Elasticsearch过滤器不适用于字符串过滤器术语

来自分类Dev

数据过滤器适用于json数据,但不适用于csv数据

来自分类Dev

文件/内容意图过滤器不适用于BroadcastReceiver,仅适用于活动

来自分类Dev

范围过滤器不适用于“gt”运算符,但适用于“lt”

来自分类Dev

用于删除不适用于 Windows 的敏感数据的 Git 过滤器分支

来自分类Dev

渗透区过滤器中的错误?Osmosis.run() 不适用于 --bounding-polygon。

来自分类Dev

DBpedia SPARQL过滤器不适用于所有结果

来自分类Dev

Logstash grok过滤器不适用于最后一个字段

来自分类Dev

Servlet过滤器不适用于容器管理的登录页面

来自分类Dev

Primefaces p:dataTable过滤器不适用于p:columns

来自分类Dev

if / else if语句不适用于PHP表单过滤器

来自分类Dev

angularjs limitTo过滤器不适用于奇数json数组

来自分类Dev

字符过滤器模式替换不适用于elasticsearch

来自分类Dev

CSS属性过滤器:invert(80%)不适用于IE

来自分类Dev

小部件“组”不适用于Tablesorter上的“过滤器”

来自分类Dev

primefaces过滤器不适用于ı和i字符

Related 相关文章

  1. 1

    在Jersey中过滤器的动态绑定不适用于子资源

  2. 2

    Angular JS Order By过滤器不适用于动态谓词

  3. 3

    angularJS ng-repeat过滤器不适用于动态字段

  4. 4

    表格过滤器不适用于退格键

  5. 5

    javascript过滤器方法不适用于getElementsByName

  6. 6

    Xfade过滤器不适用于ffmpeg

  7. 7

    HBase LESS过滤器不适用于字节

  8. 8

    列过滤器不适用于行分组

  9. 9

    数组过滤器不适用于状态

  10. 10

    C中的过滤器程序不适用于更复杂的图像

  11. 11

    意图过滤器不适用于Android中的ActivityTestRule

  12. 12

    表中的过滤器 (ngRepeat) 不适用于所有列

  13. 13

    boto3 中的 describe_snapshots 过滤器不适用于“描述”字段

  14. 14

    Elasticsearch过滤器不适用于字符串过滤器术语

  15. 15

    数据过滤器适用于json数据,但不适用于csv数据

  16. 16

    文件/内容意图过滤器不适用于BroadcastReceiver,仅适用于活动

  17. 17

    范围过滤器不适用于“gt”运算符,但适用于“lt”

  18. 18

    用于删除不适用于 Windows 的敏感数据的 Git 过滤器分支

  19. 19

    渗透区过滤器中的错误?Osmosis.run() 不适用于 --bounding-polygon。

  20. 20

    DBpedia SPARQL过滤器不适用于所有结果

  21. 21

    Logstash grok过滤器不适用于最后一个字段

  22. 22

    Servlet过滤器不适用于容器管理的登录页面

  23. 23

    Primefaces p:dataTable过滤器不适用于p:columns

  24. 24

    if / else if语句不适用于PHP表单过滤器

  25. 25

    angularjs limitTo过滤器不适用于奇数json数组

  26. 26

    字符过滤器模式替换不适用于elasticsearch

  27. 27

    CSS属性过滤器:invert(80%)不适用于IE

  28. 28

    小部件“组”不适用于Tablesorter上的“过滤器”

  29. 29

    primefaces过滤器不适用于ı和i字符

热门标签

归档