Hi Bruno,
You are understanding things correctly. A proxy is injected that
defers to a thread local instance. Thus you have to ensure that you
always access the proxy from the invoking thread.
Are you aware of Jersey's @PreSession life-cycle support? Annotate a
class with @PerSession and one instance will be created per session.
BTW i do not recommend utilizing sessions for building RESTful Web
services as it breaks the stateless constraint.
Paul.
On Oct 24, 2009, at 6:15 AM, Bruno de Carvalho wrote:
> 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
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>