简体   繁体   中英

Jaxrs Filter at Resource Locator

I'm trying to intercept requests to my jaxrs apis basead on annotations, my filter is simple:

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

this works fine with a simple resource like this: (works both in class and method)

@Path("/")
public class SimpleResource {

    @GET
    @MyCustomAnnotation
    public String test() {
       return "test";
    }

}

But in my real application, I have scenarios like this:

@Path("/")
public class RootResource {

   @Inject
   ChildResource childResource;

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

So, I wanna put my custom annotation only on ResourceLocator and on the fly verify that the final resource contains the annotation.

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

   @Inject
   ChildResource childResource;

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

is it possible? or i can only get information about the matched resource?

"In jersey how would be this?"

With Jersey you have access to the resource model, and ways to traverse the model. You can see jersey server introspectionmodeller not public in v2.0? for some explanation and examples of how to traverse the model and Resource and ResourceMethod . Other than that, there is not much documentation these APIs.

Below is a complete example Using Jersey Test Framework . You can run the class like any other JUnit test. You just need this one dependency to run it

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

And here's the test.

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"));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM