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 19:06:25 +0100

I see, if you have a property with the base uri, then it is probably
easiest to do everything in the constructor of your root resource.
Martin

On 9.3.2011 18:59, Martynas Jusevicius wrote:
> 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
>>>>>>
>>>>>>