资源定位器上的Jaxrs过滤器



我试图拦截请求到我的jaxrs api基于注释,我的过滤器很简单:

@Provider
public class Filter implements ContainerRequestFilter {
    @Context
    private ResourceInfo info;

    @Override
    public void filter(ContainerRequestContext crc) throws IOException {
        // here I'm trying to get the annotate resource class or method.
        info.getResourceClass().isAnnotationPresent(MyCustomAnnotation.class);
    }
}

对于这样一个简单的资源(在类和方法中都有效)

@Path("/")
public class SimpleResource {
    @GET
    @MyCustomAnnotation
    public String test() {
       return "test";
    }
}

但是在我的实际应用中,我有这样的场景:

@Path("/")
public class RootResource {
   @Inject
   ChildResource childResource;
   @Path("child")
   public ChildResource child () {
       return childResource;
   }
}

所以,我想把我的自定义注释只放在ResourceLocator上并动态地验证最终的资源是否包含这个注释

@Path("/")
@CustomAnnotation
public class RootResource {
   @Inject
   ChildResource childResource;
   @Path("child")
   public ChildResource child () {
       return childResource;
   }
}

是可能的吗?还是只能得到匹配资源的信息?

"在新泽西会是什么样子?"

使用Jersey,您可以访问资源模型,以及遍历模型的方法。你可以看到jersey server introspectionmodeler在v2.0中不是公共的?为如何遍历模型和ResourceResourceMethod提供一些解释和示例。除此之外,这些api没有太多的文档。

下面是使用Jersey测试框架的完整示例。您可以像运行任何其他JUnit测试一样运行这个类。你只需要这个依赖项来运行它

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.19</version>
    <scope>test</scope>
</dependency>

这是测试

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.List;
import java.util.logging.Logger;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import static junit.framework.Assert.assertEquals;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ExtendedUriInfo;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.model.Resource;
import org.glassfish.jersey.server.model.ResourceMethod;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
public class ResourceModelTest extends JerseyTest {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface ResourceAnnotation {
        String value();
    }
    @Path("root")
    @ResourceAnnotation("SomeValue")
    public static class ParentResource {
        @Path("sub")
        public ChildResource getChild() {
            return new ChildResource();
        }
        @GET
        public String get() {
            return "ROOT";
        }
    }
    public static class ChildResource {
        @GET
        public String get() {
            return "CHILD";
        }
    }
    @Provider
    public static class ResourceFilter implements ContainerResponseFilter {
        @Override
        public void filter(ContainerRequestContext requestContext,
                ContainerResponseContext responseContext) throws IOException {
            ExtendedUriInfo info = (ExtendedUriInfo) requestContext.getUriInfo();
            List<ResourceMethod> resourceLocators = info.getMatchedResourceLocators();
            if (!resourceLocators.isEmpty()) {
                Resource parent = resourceLocators.get(0).getParent();
                Class<?> parentClass = parent.getHandlerClasses().iterator().next();
                ResourceAnnotation anno = parentClass.getAnnotation(ResourceAnnotation.class);
                if (anno != null) {
                    responseContext.getHeaders().putSingle("X-SubResource-Header", anno.value());
                }
            }
        }
    }
    @Override
    public ResourceConfig configure() {
        return new ResourceConfig(ParentResource.class)
                .register(ResourceFilter.class);
    }
    @Override
    public void configureClient(ClientConfig config) {
        config.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
    }
    @Test
    public void get_child_resource() {
        Response response = target("root/sub").request().get();
        assertEquals(200, response.getStatus());
        assertEquals("SomeValue", response.getHeaderString("X-SubResource-Header"));
    }
}

最新更新