Hi Paul,
I'm actually reluctant to use sessions too, but the issue here is that the REST interface is part of a multi-protocol interface to a server, that already has SIP, RTMP (flash) and another custom TCP interface - all these interfaces share the concept of a session, so the HTTP should (must?) follow the same lines.
There's a translation layer between protocols and the server core, so no matter where the request comes from/goes to, it's always seen (from the core of the server) as being the same kind. All these requests are associated with a "Client" (interface), so I was using the http sessions to create an HttpClient and keep it between requests, in order not to have each and every request need authentication.
I know it goes against REST principles, but it's the only way to keep things completely uniform regardless of client protocol. Still, I'm inclined to change it in the near future and add support for operations outside a session :)
Regarding the @PerSession, you mean if I annotate my HttpClient class with @PerSession, each http session would have its own HttpClient class? Reading the API it seems so, but how then would I access this instance from my resource class? I'd like to completely avoid using @Context HttpServlet* on the resource (and it's methods).
I currently have something like:
@GET
public void someMethod(@Context Client client, ...) { ... }
And then I have my ClientContextProvider which injects a Client instance, fetched from the HttpSession.
As a side note, I've been looking at Jersey's source code and this has some *REALLY* cool stuff in it :))
Best regards,
Bruno
-----Original Message-----
From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: segunda-feira, 26 de Outubro de 2009 08:33
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Doubts regarding @Context proxies.
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
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
For additional commands, e-mail: users-help_at_jersey.dev.java.net