users@jersey.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 28 Feb 2008 12:08:09 +0100

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.
>>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109