我在理解休息拦截器注释如何添加后来在过滤器中可见的不同值方面有点挣扎。鉴于下面的代码,我希望一旦在过滤器中,权限值将包含foo和bar,但它们是空的。任何帮助将不胜感激。
注释
package edu.psu.swe.fortress.poc.interceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.ws.rs.NameBinding;
@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface FortressProtected
{
@Nonbinding String[] permissions() default {};
}
过滤
package edu.psu.swe.fortress.poc.interceptor;
import java.io.IOException;
import java.lang.annotation.Annotation;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
@Provider
@FortressProtected
public class FortressAuthorizer implements ContainerRequestFilter
{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
System.out.println("In the interceptor");
Class<?> clazz = this.getClass();
FortressProtected annotation = clazz.getAnnotation(edu.psu.swe.fortress.poc.interceptor.FortressProtected.class);
System.out.println("Annotation? " + clazz.isAnnotation());
for (Annotation a : clazz.getAnnotations())
{
System.out.println(a);
}
for (String s : annotation.permissions())
{
System.out.println(s);
}
}
}
App config
package edu.psu.swe.fortress.poc.rest;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import edu.psu.swe.fortress.poc.interceptor.FortressAuthorizer;
import edu.psu.swe.fortress.poc.interceptor.FortressProtected;
@ApplicationPath("")
public class FortressTestApp extends Application
{
private Set<Class<?>> clazzez_ = new HashSet<>();
{
clazzez_.add(ResourceImpl.class);
clazzez_.add(FortressProtected.class);
clazzez_.add(FortressAuthorizer.class);
}
public Set<Class<?>> getClasses()
{
return clazzez_;
}
}
资源类
package edu.psu.swe.fortress.poc.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import edu.psu.swe.fortress.poc.interceptor.FortressProtected;
@FortressProtected(permissions={"foo", "bar"})
@Path("tests")
public class ResourceImpl
{
@GET
@Produces("application/text")
public String getHello()
{
FortressProtected annotation = this.getClass().getAnnotation(edu.psu.swe.fortress.poc.interceptor.FortressProtected.class);
System.out.println(annotation.toString());
return "hello";
}
}
日志输出如下:
15:59:55,223 INFO [stdout](默认任务-9)@ edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions = []) 15:59:55,229 INFO [stdout](默认任务-9)@ edu.psu.swe.fortress.poc.interceptor.FortressProtected(permissions = [foo,bar])
提前致谢。
答案 0 :(得分:14)
在过滤器中查看此内容
Class<?> clazz = this.getClass();
FortressProtected annotation = clazz.getAnnotation(FortressProtected.class);
this.getClass()
对应于过滤器类(其注释具有无值)。您需要在ResourceImpl
两种选择。您可以明确使用ResourceImpl.class.getAnnotation(...)
。但问题是,一旦绑定了多个类,如何匹配哪个类对应哪个请求。因此,下一个选项更加可行。
你做的是注入ResourceInfo
。有了这个,您可以调用它的getResourceMethod
或getResourceClass
方法。这些方法分别返回匹配的方法和类。然后,您可以在类级别以及方法级别检查注释(因为我们也允许在方法级别绑定)。所以你可能会有更多的东西:
@Provider
@FortressProtected
public class FortressAuthorizer implements ContainerRequestFilter {
@Context
ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
Class<?> resourceClass = resourceInfo.getResourceClass();
FortressProtected classAnnot = resourceClass.getAnnotation(FortressProtected.class);
if (classAnnot != null) {
// do something with annotation
}
Method resourceMethod = resourceInfo.getResourceMethod();
FortressProtected methodAnnot = resourceMethod.getAnnotation(FortressProtected.class);
if (methodAnnot != null) {
// do something with annotation
}
}
}