users@jersey.java.net

[Jersey] Re: UriInfo injection at resource initialization time

From: Martynas Jusevicius <martynas.jusevicius_at_gmail.com>
Date: Wed, 9 Mar 2011 18:59:40 +0100

Thanks.

I would have to do the whole model in one go, because the
representation methods of the root resource are already going to run
queries on it.

Do you think it's a better idea than storing base URI in some property
file and using say ServletContextListener for initialization?

On Wed, Mar 9, 2011 at 6:42 PM, Martin Matula <martin.matula_at_oracle.com> wrote:
> 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
>>>>>
>>>>>
>