users@jersey.java.net

[Jersey] Re: UriInfo injection at resource initialization time

From: Martynas Jusevicius <martynas.jusevicius_at_gmail.com>
Date: Fri, 11 Mar 2011 16:40:01 +0100

There still several things I don't understand, e.g. in which
circumstances are @Context fields initialized? I have

abstract public class Resource
{
    @Context ServletContext context;

    public Resource(Resource parent)
    {
        super(parent);
    }

    @GET
    @Produces(MediaType.TEXT_HTML)
    public View doGet(@Context HttpServletRequest request, @Context
HttpServletResponse response) throws Exception
    {
        System.out.println("Resource: " + this + "Method: @GET
ServletContext: " + context);
    }

}

@Path("")
public class RootResource extends Resource
{
    public RootResource(@Context UriInfo uriInfo)
    {
        super(null);
    }

    @Override
    @GET
    public View doGet(@Context HttpServletRequest request, @Context
HttpServletResponse response) throws Exception
    {
        super.doGet(request, response);
    }

    @Path(SubResource.PATH)
    public SubResource getSubResource(@Context UriInfo uriInfo)
    {
        return new SubResource(this, uriInfo);
    }
}

public class SubResource extends Resource
{
    public static final String PATH = "sub";

    public SubResource(RootResource parent, @Context UriInfo uriInfo)
    {
        super(parent);
    }

    @Override
    @GET
    public View doGet(@Context HttpServletRequest request, @Context
HttpServletResponse response) throws Exception
    {
        super.doGet(request, response);
    }
}

It seems that only the root resource gets context initialized, not the
subresource - even though they extend the same superclass which holds
the injected field, so I would expect the same behaviour. And I mean
request methods here, not constructors. The output:

Resource: RootResource_at_fdde57 Method: @GET ServletContext:
org.apache.catalina.core.ApplicationContextFacade_at_12cb562
Resource: SubResource_at_150d191 Method: @GET ServletContext: null

What am I missing again? Is it the same issue as here:
http://jersey.576304.n2.nabble.com/Instatiating-subResources-with-Context-class-fields-td5360153.html

Thanks again,

Martynas

On Fri, Mar 11, 2011 at 2:27 PM, Martynas Jusevicius
<martynas.jusevicius_at_gmail.com> wrote:
> Ok, maybe @PostConstruct Resource initialization will actually do...
> Seems to work.
>
> On Fri, Mar 11, 2011 at 1:28 PM, Martynas Jusevicius
> <martynas.jusevicius_at_gmail.com> wrote:
>> Hey Marek (I can see only people with names starting "M" participate
>> in this thread :)),
>>
>> I was able to achieve what I wanted with plain Servlet, without JAX-RS
>> :) But since JAX-RS is a RESTful framework, I think it could provide
>> more useful shortcuts and helpers - just like it provides UriInfo and
>> not only ServletRequest.
>>
>> I got my classes and URIs to work, but since I don't use @Singleton
>> anymore, I can see that root resource gets a new instance with each
>> request (makes sense) and this is probably what is giving me PermGen
>> exceptions which I haven't seen before.
>> So I still need to the declare the root singleton, but then I'd get
>> the same IllegalStateException - which brings me back to base one...
>> Any other solutions?
>> JAX-RS is giving me a hard time in getting it to work with my setup.
>>
>> Martynas
>>
>> On Fri, Mar 11, 2011 at 11:51 AM, Marek Potociar
>> <marek.potociar_at_oracle.com> wrote:
>>> Mi Martynas,
>>>
>>> On 03/11/2011 01:17 AM, Martynas Jusevicius wrote:
>>>> Hey Martin,
>>>>
>>>> well I've worked on my own RESTful framework based on Serlvet for
>>>> several years now, and built 3-4 apps on it.
>>>> It resembles JAX-RS a great deal: tree of resources/subresources,
>>>> singletons/root classes, HTTP methods, representations etc, but uses
>>>> object-oriented methods rather than annotations.
>>>>
>>>> However I can see (with my current knowledge) several features that
>>>> JAX-RS could benefit from:
>>>> 1. a way for the resources to access their parent resource (class) in the tree
>>>
>>> Can't you just pass the parent references into subresources when constructing them?
>>>
>>>> 2. a way for resource instances to access their own URI during
>>>> request, as opposed to the request URI.
>>>> Maybe an injectable class like ResourceInfo would do, as a supplement
>>>> to UriInfo.
>>>
>>> I thought you were able to achieve that, weren't you? Perhaps we may just need to clean up or extend the UriInfo API
>>> somehow?
>>>
>>>> 3. an easier way for the resource to check if it is a leaf of the
>>>> matching resource tree, i.e. that it matches the URI to the last path
>>>> segment. Maybe an annotation like @Leaf would be useful to prevent
>>>> attaching any subresources.
>>>
>>> Maybe I have missed the use case in the previous emails, but doesn't a resource method wihtout any @Path annotation
>>> achieves that? I mean that it is invoked once the leaf resource is reached, e.g.:
>>>
>>> @Path("/")
>>> Resource {
>>>   @Path("{segment}")
>>>   public SubResource getSubresource() {
>>>      return new SubResource();
>>>   }
>>>
>>>   @GET
>>>   public String get() {
>>>      return "No segments. Root is a leaf";
>>>   }
>>> }
>>>
>>> Resource {
>>>   @Path("{segment}")
>>>   public SubResource getSubresource() {
>>>      return new SubResource();
>>>   }
>>>
>>>   @GET
>>>   public String get(@PathParam("segement") last) {
>>>      return "Leaf subresource reached. Last segment: " + last;
>>>   }
>>> }
>>>
>>> I think the above may also solve the item 4 on your list: Also note that the path param is propagated from
>>> getSubresource() to get() method.
>>>
>>> Marek
>>>
>>>
>>>> 4. a way to define a relationship between the URI template param like
>>>> @Path("{id}") and the subresource method from which the param is
>>>> built, maybe reusing @PathParam() annotation, e.g.
>>>>
>>>> public class RootResource
>>>> {
>>>>   @Path("{id}")
>>>>   public SubResource getSubResource()
>>>>   {
>>>>     return new SubResource(id);
>>>>   }
>>>> }
>>>>
>>>> public class SubResource
>>>> {
>>>>   private String id = null;
>>>>
>>>>   public SubResource(@PathParam("id") String id)
>>>>   {
>>>>     this.id = id;
>>>>   }
>>>>
>>>>   @PathParam("id") // marks method used as "id" template param
>>>>   public String getId()
>>>>   {
>>>>     return id;
>>>>   }
>>>> }
>>>>
>>>> It would not be of much use when looking up resources, but could help
>>>> building them in case my #2 suggestion is implemented (it's what I
>>>> used the abstract Resource.getPath() method for).
>>>>
>>>> Sorry if some of this is already present in JAX-RS, I've only been
>>>> developing with it for about a week.
>>>> Hope this helps.
>>>>
>>>> Martynas
>>>> semantic-web.dk
>>>>
>>>> On Thu, Mar 10, 2011 at 6:52 PM, Martin Matula <martin.matula_at_oracle.com> wrote:
>>>>> Hi Martynas,
>>>>>
>>>>> On 10.3.2011 16:23, Martynas Jusevicius wrote:
>>>>> ....
>>>>>>
>>>>>> I see this as a normal (if not common) RESTful use case, so I'm pretty
>>>>>> unimpressed that JAX-RS doesn't help out here :)
>>>>>
>>>>> We welcome proposals for improvements. :)
>>>>> Martin
>>>>>
>>>
>>
>