2015-10-13 88 views
1

我试图拦截请求,我JAXRS basead上标注的API,我的过滤器很简单:JAXRS在资源定位器过滤

@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; 
    } 
} 

小号o,我想仅将我的自定义注释放在ResourceLocator上并实时验证最终资源是否包含注释。

@Path("/") 
@CustomAnnotation 
public class RootResource { 

    @Inject 
    ChildResource childResource; 

    @Path("child") 
    public ChildResource child() { 
     return childResource; 
    } 
} 

是否有可能?或者我只能得到有关匹配资源的信息?

+0

是否存在您正在使用的特定JAX-RS实现?还是你想保持它的标准?使用这些标准API将会很困难。 Jersey有一个API可以让你遍历资源模型。不知道其他实现。标准JAX-RS没有任何API来处理这个问题。 –

+0

即时通讯使用resteasy。在球衣上这将是怎样的? –

回答

0

“在球衣怎么会是这样?”

使用Jersey,您可以访问资源模型以及遍历模型的方法。你可以看到jersey server introspectionmodeller not public in v2.0?的一些解释和如何穿越模型和ResourceResourceMethod的例子。除此之外,这些API没有太多的文档。

下面是一个完整的示例使用Jersey Test Framework。您可以像任何其他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")); 
    } 
}