users@jersey.java.net

[Jersey] Re: UriInfo injection at resource initialization time

From: Martin Matula <martin.matula_at_oracle.com>
Date: Wed, 09 Mar 2011 18:42:35 +0100

Either you can lazily initialize the Individuals in your resources -
i.e. getIndividual() method can take UriInfo as a parameter and can
lazily initialize the individual instance variable if it is null, and
return its content otherwise (this would have to be in a synchronized
block):
public abstract class AbstractResource {
     private Individual i;

     public synchronized Individual getIndividual(UriInfo uriInfo) {
         if (i == null) {
             i = new Individual(uriInfo.getAbsolutePath());
         }
         return i;
     }
}

@Path("/")
@Singleton
public class TestRootResource extends AbstractResource {
     @GET
     @Produces("text/plain")
     public String doGet(@Context UriInfo uriInfo) {
         return "TestResource.doGet() - Individual: " +
getIndividual(uriInfo);
     }
}

@Path("/sub")
@Singleton
public class TestSubResource extends AbstractResource {
     @GET
     @Produces("text/plain")
     public String doGet(@Context UriInfo uriInfo) {
         return "TestSubResource.doGet() - Individual: " +
getIndividual(uriInfo);
     }
}

Or you can do eager initialization of the whole model on the first
request and use subresource locators - e.g. this should work:

public abstract class AbstractResource {
     private Individual i;
     AbstractResource() {
     }

     AbstractResource(URI uri) {
         initIndividual(uri);
     }

     void initIndividual(URI uri) {
         System.out.println(uri);
         i = ///
     }
}

@Path("/")
@Singleton
public class TestRootResource extends AbstractResource {
     private TestSubResource subResource;

     private synchronized void init(UriInfo uriInfo) {
         if (subResource == null) {
             initIndividual(uriInfo.getAbsolutePath());
             subResource = new
TestSubResource(uriInfo.getAbsolutePathBuilder().path(TestSubResource.PATH).build());
         }
     }

     @GET
     @Produces("text/plain")
     public String doGet(@Context UriInfo uriInfo) {
         init(uriInfo);
         return "TestResource.doGet()";
     }

     @Path(TestSubResource.PATH)
     public TestSubResource getSubResource(@Context UriInfo uriInfo) {
         init(uriInfo);
         return subResource;
     }
}

// no annotations needed here
public class TestSubResource extends AbstractResource {
     public static final String PATH = "sub";

     TestSubResource(URI uri) {
         super(uri);
     }

     @GET
     @Produces("text/plain")
     public String doGet() {
         return "TestSubResource.doGet()";
     }
}

Hope this helps.
Martin

On 9.3.2011 18:06, Martynas Jusevicius wrote:
> Sorry Martin, you're right! Base URI was set on each request...
>
> I was so fixated on getting UriInfo to work and use it to lookup
> resources in the RDF model that I forgot that model had to be
> initialized in the first place.
>
> Now I see what you're saying - since I need absolute URIs to
> initialize RDF and they cannot be resolved without base URI, this
> needs to be done within the request context. This is not even JAX-RS
> specific, it's just that I'm implementing RDF and JAX-RS at the same
> time..
>
> And when I have the base URI of the request, I can build an absolute
> one using UriBuilder.fromResource(class).build(), right?
> The question is, where should I put the initialization? In @GET of the
> root Resource and mark it with some flag so it only runs once?
> Or is there a better hook for that?
>
> Martynas
>
> On Wed, Mar 9, 2011 at 5:01 PM, Martin Matula<martin.matula_at_oracle.com> wrote:
>> I still don't see how that gets you any more further than
>> UriBuilder.fromResource(class).build().
>> The root resource needs to figure out the server name, port, context path
>> and server mapping. How did you get that without the request context?
>> If you figured out how to get the "base URI" it for your servlet outside of
>> the request context, you can do the same thing for your JAX-RS resources and
>> then just do UriBuilder.fromUri(baseUri).path(Resource.class).build().
>> Martin
>>
>> On 9.3.2011 16:49, Martynas Jusevicius wrote:
>>> I had a recursive Resource.getAbsolutePath() which went up the parent
>>> tree concatenating getPath().
>>>
>>> For singletons I could get the URI like this:
>>> SearchResource.getInstance().getAbsolutePath().
>>>
>>> For other Resources the mapping happened within the request.
>>>
>>> On Wed, Mar 9, 2011 at 4:31 PM, Martin Matula<martin.matula_at_oracle.com>
>>> wrote:
>>>> Hi Martynas,
>>>>
>>>> On 9.3.2011 15:59, Martynas Jusevicius wrote:
>>>>>>> I had achieved the same using abstract Resource superclass (like in my
>>>>>>> last example) with
>>>>>>> - getPath() and getAbsolutePath() equivalents
>>>>>>> - constructor Resource(Resource parent) - effectively building a
>>>>>>> parent/child tree of Resource instances
>>>>>>> - Servlet-like doGet(), doPost() etc methods
>>>>>>> and the real HttpServlet mapping request URIs to Resource instances
>>>>>>> and executing the appropriate do..() methods.
>>>> I mean, how did you get the absolute URI outside of the request context?
>>>> I
>>>> am guessing all the above initialization happened upon the first request
>>>> within it's context, no?
>>>> Martin
>>>>
>>>>