Annotation needs to be treated by some code.
You need to create a filter, that processes your custom annotation, before your method is called.
see : https://jersey.java.net/documentation/latest/filters-and-interceptors.html
Creating a filter, should be fairly easy, but it is not enough. It will get called, but won't know in what context it will be called. By context, I mean which class / method will be called right after the filter is executed. In this example I assumed your annotation (called MyCustomAnnotation) can be applied to class / method.
For this, you need to create a "Dynamic Feature" that will bind a different instance of the filter, for each possible context.
In details :
For a given JAX-RS class :
@MyCustomAnnotation(name="someVal")
class MyClass{
@GET
@MyCustomAnnotation(name="someConfig")
public Object myMethod(){
...
}
@GET
@MyCustomAnnotation(name="otherConfig")
public Object myOtherMethod(){
...
}
}
First, create your annotation (I guess you know, but just to be clear) :
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String name() default "";
}
Then, create a filter.
Notice the special constructor. A different instance of the filter will be created for each possible context. The right instance of the filter will be used in a specific context. This way it will know in what context (Class / Method) is is called. This way, using intro-spectation, your filter can behave however you like, based of the annotation you used on your target class and/or method :
@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
}
}
Ok, so now we have an annotation, a filter that process this annotation, now we need to bind dynamically to class / methods that are annotated
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()));
}
}
}
In your JAX-RS configuration... register your new DynamicFeature
public class MyRestConfig extends ResourceConfig {
public RestConfig() {
// your configs...
packages("com.yourpackage.rest");
// ...
// handle @MyCustomAnnotation annotations
register(MyFilterDynamicFeature.class);
// ...
}
}
I hope this is clear. Recap of what you need to do
- create your annotation
- annotate your JAX-RS class / method with your annotation
- create a filter that will process your annotation
- create a dynamic feature, that will bind a different instance of the filter for each different context (method / class combination, where at least one or the other is annotated with your annotation)
- register the dynamic feature in your rest config
----Update--------
Rather than using the Dynamic Feature, you should be able to inject the ressource info at runtime
@Context
private ResourceInfo resourceInfo;