Hello,
In my project, I need http sessions across multiple REST requests (mainly for authentication purposes).
I noticed there's nothing in the API that directly supports sessions so I'd have to roll in my own system or, since I'm running the app from inside a Servlet container, rely on the HttpSession API.
By using:
@GET
public Response someMethod(@Context HttpServletRequest request) { ... }
I can get the request, access the session, store/load whatever I need, etc. Thing is I really don't want to be repeating all that boilerplate code all over the place. I could just pull that to a function, but I'd still have to call that function all over the place.
I'd rather have something more along the lines of:
@GET
public Response someMethod(@Context MySession session) { ... }
After this, I'd have a layer of AOP that tests if session exists (for all the methods but the login in the REST API) and throw a WebApplicationException if not, before entering the resource method.
So the flow would go: Inject session -> AOP advice that tests session -> business logic.
My doubt here is regarding the InjectableProvider/Injectable. I have this:
public class MySessionContextProvider
implements InjectableProvider<Context, Type>, Injectable<MySession> {
private HttpServletRequest request;
public MySessionContextProvider(@Context HttpServletRequest request) {
this.request = request;
}
...
@Override
public MySession getValue() {
MySession bean = new MySession();
bean.setThreadName(Thread.currentThread().getName());
bean.setRequestId(this.request.toString());
return bean;
}
}
It's a really stupid example but I was just trying out whether having the "request" being passed in as a constructor parameter would work. It didn't make much sense, as this injectable provider would be instanced only once (I confirmed this with console print on the constructor) so even if that HttpServletRequest parameter was available at bootup time, it'd be the same for all requests, which would be a wrong behavior.
To my great surprise I found that this code actually seems to work as expected! I figured this "request" couldn't be an HttpServletRequest but rather a Proxy, which I found out to be true -- and, after a bit of digging in the sources, that the class of this proxy was the same as the "instance" passed to the HttpServletRequest provider created in WebComponent, so I guess that's where it comes from.
Reading a bit more of the sources, the whole thing started to make sense. After testing with 4 different browsers at the same time and getting different HttpServletRequest objects and being executed by different threads, this seems to be true. Almost too good to be true :)
Am I understanding this right? Each time the "getValue()" gets called, a different HttpServletRequest will be in use, even though it seems to be the same variable in a single-instance provider?
Best regards,
Bruno