资源定位器中的 Jaxrs 过滤器
Jaxrs Filter at Resource Locator
我试图根据注释拦截对我的 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);
}
}
这适用于像这样的简单资源:(适用于 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;
}
}
可能吗?或者我只能获取匹配资源的信息?
"In jersey how would be this?"
通过 Jersey,您可以访问资源模型以及遍历模型的方法。您可以查看 了解如何遍历模型的一些解释和示例以及 Resource
和 ResourceMethod
。除此之外,这些 API 的文档不多。
下面是使用 Jersey Test Framework 的完整示例。您可以像任何其他 JUnit 测试一样 运行 class。你只需要 运行 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>
这是测试。
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"));
}
}
我试图根据注释拦截对我的 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);
}
}
这适用于像这样的简单资源:(适用于 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;
}
}
可能吗?或者我只能获取匹配资源的信息?
"In jersey how would be this?"
通过 Jersey,您可以访问资源模型以及遍历模型的方法。您可以查看 Resource
和 ResourceMethod
。除此之外,这些 API 的文档不多。
下面是使用 Jersey Test Framework 的完整示例。您可以像任何其他 JUnit 测试一样 运行 class。你只需要 运行 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>
这是测试。
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"));
}
}