I am working with Spring 5.2.x together with Jersey 2.30.x for JAX-RS.
I have an annotation as following:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
}
In my service, I use this annotation as following:
@Service
public class MyService {
@MyAnnotation
public Response get() {
...
}
}
I want to execute certain logic when the @MyAnnotation
annotation is present. For this, I created an aspect:
@Aspect
@Component
public class MyAspect {
@Context
private ContainerRequest request;
@Pointcut("@annotation(so.MyAnnotation)")
public void annotated() {
}
@Before("annotated()")
public void test() {
System.out.println("I need access to the HTTP headers: " + request);
}
}
In this aspect, I need access to the HTTP headers. I tried injecting Jersey's ContainerRequest
, but this seems to fail: the reference is always null
.
So my question is: how can I access Jersey's contextual objects, such as ContainerRequest
, in Spring's managed beans?
minimal example
I created a minimal example, see https://github.com/pbillen/playground-so-61750237. You can build it with mvn clean install -U
and then start a Tomcat container with mvn cargo:run
. If you then point your browser to http://localhost:8080/, you will see in the console:
I need access to the HTTP headers: null
working solution, by bypassing Jersey and using HttpServletRequest
I tried wiring HttpServletRequest
in the aspect and then accessing the Authorization
header:
@Aspect
@Component
public class MyAspect {
@Autowired
private HttpServletRequest request;
@Pointcut("@annotation(so.MyAnnotation)")
public void annotated() {
}
@Before("annotated()")
public void test() {
System.out.println(request.getHeader("authorization"));
}
}
I also added to web.xml
:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
This basically bypasses Jersey completely. This seems to work, I can now read out the Authorization
header in the aspect. Great!
But, my question still stands: is there a way to inject Jersey's context objects into a Spring-managed aspect?