使用注释在Jersey中写入ServletContext。

时间:2015-11-10 15:26:08

标签: java annotations jersey jax-rs

我有一个这样的课程:

   public class MyResource(){

       public MyResource(@Context ServletContext context){
            context.setAttribute("someAttribute","someVal");
       }

       @PUT
       public void someMethod(){
         ...
       }
   }

我希望使用注释(即JAX-RS / Jersey读取注释的值并将其写入ServletContext,以便我可以在请求范围内注入ServletContext的其他位置访问此值。)< / p>

@MyCustomAnnotation(name="someVal")
public class MyResource(){


}

1 个答案:

答案 0 :(得分:4)

注释需要由某些代码处理。

在调用方法之前,您需要创建一个处理自定义注释的过滤器。

请参阅:https://jersey.java.net/documentation/latest/filters-and-interceptors.html

创建过滤器应该相当容易,但还不够。它会被调用,但不会知道它将在什么上下文中被调用。根据上下文,我的意思是在执行过滤器之后立即调用哪个类/方法。在这个例子中,我假设您的注释(称为MyCustomAnnotation)可以应用于类/方法。

为此,您需要创建一个“动态特征”,它将为每个可能的上下文绑定过滤器的不同实例。

详情:

对于给定的JAX-RS类:

@MyCustomAnnotation(name="someVal")
class MyClass{

    @GET
    @MyCustomAnnotation(name="someConfig")
    public Object myMethod(){
    ...
    }

    @GET
    @MyCustomAnnotation(name="otherConfig")
    public Object myOtherMethod(){
    ...
    }

}

首先,创建你的注释(我想你知道,但只是为了清楚):

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {

    String name() default "";

}

然后,创建一个过滤器。 注意特殊的构造函数。将为每个可能的上下文创建不同的过滤器实例。过滤器的正确实例将在特定上下文中使用。这样它就会知道调用什么上下文(Class / Method)。这样,根据您在目标类和/或方法上使用的注释,使用intro-spectation,您的过滤器可以根据您的喜好运行:

@Priority(Priorities.AUTHORIZATION - 1)
public class MyFilter implements ContainerRequestFilter {

    private final Class<?> _class;
    private final Method method;
    private MyCustomAnnotation classAnnotation;
    private MyCustomAnnotation methodAnnotation;

    public MyFilter(Class<?> _class, Method method) {

        this._class = _class;
        this.method = method;

        this.classAnnotation = _class.getAnnotation(MyCustomAnnotation.class);
        this.methodAnnotation = method.getAnnotation(MyCustomAnnotation.class);

    }

    @Override
    public void filter(ContainerRequestContext requestContext) {

        // your code goes here!

        // based on classAnnotation and/or methodAnnotation, 
        // add whatever you want to the requestContext

    }
}

好的,现在我们有一个注释,一个处理这个注释的过滤器,现在我们需要动态绑定到带注释的类/方法

public class MyFilterDynamicFeature implements DynamicFeature {

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext configuration) {

        //if the class or the method is annotated, bind a new instance of our filter to this method
        if(resourceInfo.getResourceClass().getAnnotation(MyCustomAnnotation.class)!=null || resourceInfo.getResourceMethod().getAnnotation(MyCustomAnnotation.class)!=null){            
            configuration.register(new MyFilter(resourceInfo.getResourceClass(), resourceInfo.getResourceMethod()));
        }

    }
}

在您的JAX-RS配置中...注册您的新DynamicFeature

public class MyRestConfig extends ResourceConfig {

    public RestConfig() {

        // your configs...

        packages("com.yourpackage.rest");

        // ...

        // handle @MyCustomAnnotation annotations
        register(MyFilterDynamicFeature.class);

        // ...    
    }

}

我希望这很清楚。回顾一下你需要做什么

  1. 创建注释
  2. 使用您的注释
  3. 注释您的JAX-RS类/方法
  4. 创建一个处理您的注释的过滤器
  5. 创建一个动态功能,它将为每个不同的上下文绑定不同的过滤器实例(方法/类组合,其中至少有一个或另一个用注释注释)
  6. 在rest config中注册动态功能
  7. ----的更新 --------

    您应该能够在运行时注入资源信息

    ,而不是使用动态功能
    @Context
    private ResourceInfo resourceInfo;