有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用注释写入Jersey中的ServletContext。

我有一门课是这样的:

   public class MyResource(){

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

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

我希望使用注释(即JAX-RS/Jersey读取注释的值并将其写入ServletContext,以便我可以在请求范围中注入ServletContext的其他地方访问该值。)

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


}

共 (1) 个答案

  1. # 1 楼答案

    注释需要由一些代码处理

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

    见: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 "";
    
    }
    

    然后,创建一个过滤器。 请注意特殊构造函数。将为每个可能的上下文创建不同的筛选器实例。过滤器的正确实例将在特定上下文中使用。通过这种方式,它将知道在什么上下文中(类/方法)被调用。这样,使用内省,您的过滤器可以根据您在目标类和/或方法上使用的注释,以您喜欢的方式运行:

    @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. 用注释注释JAX-RS类/方法
    3. 创建一个过滤器来处理注释
    4. 创建一个动态特性,该特性将为每个不同的上下文绑定不同的过滤器实例(方法/类组合,其中至少有一个用注释注释)
    5. 在rest配置中注册动态功能

    更新

    您应该能够在运行时注入ressource信息,而不是使用动态功能

    @Context
    private ResourceInfo resourceInfo;