I have a Spring bean that needs information from the request, but isn't directly called from the controller (although it could be - but I'd like to try this without it)
Basically, my API makes requests to other services over thrift. When it makes the request, there's a service call like this:
authenticationService.authenticate(null, "username", "password");
The first parameter (the null
) is usually a "placeholder" instance of a request context. The request context contains information about the user making the request, the originating IP, etc. This way, I get all of the details about the original caller without letting my API infrastructure leak into the backend.
However, to do this, I have an InvocationHandler
that intercepts method calls made against a proxy of my service interfaces. Inside of that proxy handler, I have a RequestContextFactory
wired in that creates instances of a RequestContext
. Inside of this factory, I need to get information from the request. Particularly, the SecurityContext
, so I can identify the user making the call.
Right now, I have:
@Provider
@Component
public class WebRequestContextFactory implements RequestContextFactory {
@Context private ContainerRequest containerRequest;
public RequestContext createRequestContext() {
}
}
Unfortunately, containerRequest
is always null
.
You can use ServletRequestAttributes
to get the information from the request
and the ServletRequestAttributes
can be obtained from RequestContextHolder
:
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.currentRequestAttributes();
If the request is processed by the Spring DispatcherServlet
, there is no need of any special setup. DispatcherServlet
already expose all relevant state. But if the requests are processed outside of Spring's DispatcherServlet
, then you need to add javax.servlet.ServletRequestListener
in your application's web.xml file:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
This will associate the request with the current thread and the associated request attributes can then be retrieved via RequestContextHolder
.