users@jersey.java.net

Re: Passing around UriInfo - UriInfo.getAbsolutePathBuilder gets messed up

From: Martin Grotzke <martin.grotzke_at_javakaffee.de>
Date: Thu, 28 Feb 2008 13:58:24 +0100

Alright, thanx for this explanation!

Cheers,
Martin


On Thu, 2008-02-28 at 12:08 +0100, Paul Sandoz wrote:
> Hi Martin,
>
> Your use of the UriInfo reference is OK. You can pass it around safely
> and it is not affected by the life-cycle.
>
> I was referring to a case when you inject the Jersey specific interface:
>
> @Context HttpContextAccess context;
>
> and then cache the value returned from the following for reuse on
> subsequent requests:
>
> context.getHttpRequestContext();
>
> The HttpRequestContext instance returned from this method is not
> proxied. However the following is proxied:
>
> @Context HttpRequestContext request;
>
> Paul.
>
>
> Martin Grotzke wrote:
> > Hi,
> >
> >> It is OK. Note that on some injected instances one should be careful not
> >> to retain instances returned from the methods called on the injected
> >> instances, as they won't be thread-safe and proxied.
> > Hmm, I'm not sure what exactly you're going to say, in terms of what's
> > retained where.
> >
> > So what I do is the following:
> >
> > @Singleton
> > @Path("/users/")
> > public class UsersResource {
> >
> > @HttpContext UriInfo _uriInfo;
> >
> > @Path("{username}/")
> > public UserResource getUser(
> > @PathParam("username") final String username ) {
> > final DBUser user = getUserByUsername( username );
> > if ( user == null ) {
> > throw new NotFoundException(username + " does not exist!");
> > }
> > return new UserResource( user, _uriInfo );
> > }
> >
> > }
> >
> > public class UserResource {
> >
> > private final DBUser _user;
> > private final UriInfo _uriInfo;
> >
> > public UserResource( DBUser user, UriInfo uriInfo ) {
> > _user = user;
> > _uriInfo = uriInfo;
> > }
> >
> > @GET
> > @ProduceMime({ "application/xml" })
> > public User getUser() {
> > final User user = new User();
> > user.setUsername( _user.getUsername() );
> > user.setWidgetsListUri( _uriInfo.getAbsolutePathBuilder()
> > .clone().path( "widgets/" ).build().toString() );
> > return user;
> > }
> >
> > @Path( "widgets/" )
> > public UserWidgetsResource getWidgetsResource() {
> > return new UserWidgetsResource( _user, _uriInfo );
> > }
> >
> > }
> >
> > So several resources use the injected UriInfo. As the root resource is a
> > singleton, this should always be the same instance. Should I change the
> > root resource (UsersResource) to be a prototype, or retrieve a new
> > instance of UriInfo when creating a new resource?
> >
> > Thanx && cheers,
> > Martin
> >
> >
> >
> > On Tue, 2008-02-26 at 11:00 +0100, Paul Sandoz wrote:
> >> Martin Grotzke wrote:
> >>> Hi Paul,
> >>>
> >>> I don't know how I was able to produce the behavior I described, but now
> >>> it's not possible to reproduce this - all test are running through even
> >>> when I invoke getAbsolutePathBuilder on the same UriInfo in different
> >>> resources (but I'm sure I really experienced this ;)).
> >>>
> >> Phew! i was getting a bit worried.
> >>
> >>
> >>> So please excuse the confusion,
> >> It is OK. Note that on some injected instances one should be careful not
> >> to retain instances returned from the methods called on the injected
> >> instances, as they won't be thread-safe and proxied. Perhaps this is
> >> what led to what you experienced? This is especially important if the
> >> HttpContextAccess and obtaining request/response ifaces from that.
> >>
> >> Paul.
> >>
>