【问题标题】:Get resource class annotation values inside ContainerRequestFilter获取 ContainerRequestFilter 内的资源类注解值
【发布时间】:2015-03-22 19:02:16
【问题描述】:

我有点难以理解剩余拦截器注释如何添加稍后在过滤器中可见的不同值。鉴于下面的代码,我希望一旦在过滤器中,权限值将包含 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);
    }
  }
}

应用配置

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])

提前致谢。

【问题讨论】:

    标签: java jax-rs interceptor


    【解决方案1】:

    在你的过滤器中查看这个

    Class<?> clazz = this.getClass();
    FortressProtected annotation = clazz.getAnnotation(FortressProtected.class);
    

    this.getClass() 对应于过滤器类(其注释没有没有值)。相反,您需要在 ResourceImpl 上获取注释

    几个选项。您可以明确使用ResourceImpl.class.getAnnotation(...)。但是这样做的问题是,一旦绑定了多个类,如何匹配哪个类对应哪个请求。因此,下一个选项更可行。

    你所做的是注入ResourceInfo。有了这个,你可以称之为getResourceMethodgetResourceClass 方法。这些方法分别返回匹配的方法和类。然后,您可以在类级别和方法级别检查注释(因为我们也可以在方法级别进行绑定)。所以你可能会有更多类似的东西:

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

    【讨论】:

    • 这正是我想要的。非常感谢。
    • 非常感谢。我更喜欢another answer。因为在这篇文章中,@FortressProtected 在过滤器中进行了注释。但是我需要在 ws 方法中添加注解,并在 filter() 中进行验证。
    • @AechoLiu 那我猜你不明白这个问题。
    • 嗯,我在 2020/10 发布。我认为@FortressProtected public class FortressAuthorizer 去年误导了我,因为它在 ContainerRequestFilter 的子类上添加了注释。
    • @AechoLiu 这实际上是你使用@NameBinding时需要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2018-11-24
    • 2011-12-20
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多