users@jersey.java.net

[Jersey] Re: Root resource as a resource factory (to handle @Path("/") as well)

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Fri, 12 Oct 2012 09:40:14 -0400

Hi Martynas,

     My guess is that what you're trying to do won't work, because the
entire point of @Path is to say "the current resource handles *this*
path". Now, if you really want the sub-resource to handle it, and there
is no such thing as a parent of "/" then the only way to handle this is
declare @GET/_at_POST/etc inside RootResource and delegate to
getResource(). For example:

@Path("/")
public class RootResource
{
   @GET
   public Response get()
   {
     // implementation reuse
     return getResource().get();
   }

   @Path("{path: .*}")
   public Resource getResource()
   {
     return new Resource();
   }
}

     I've done something similar in my own code, for different reasons.
One benefit of this approach is that type-safety remains enforced at
compile-time. If the sub-resource ever changes in a way that requires
RootResource to change you are likely to get a compiler error.

Gili

On 12/10/2012 6:31 AM, Martynas Jusevičius wrote:
> Marek,
>
> sorry, this is a typo left from when I tried to split the sub-resource
> locators into 2 -- one for the base URI and one for the rest.
>
> The following code has the same effect (HTTP Status 405 - Method Not Allowed):
>
> @Path("/")
> public class RootResource
> {
>
> @Path("{path: .*}")
> public Resource getResource()
> {
> return new Resource();
> }
>
> }
>
> BTW, I'm using Jersey 1.9 -- maybe there have been some bugs in this area?
>
> Martynas
>
> On Fri, Oct 12, 2012 at 1:22 PM, Marek Potociar
> <marek.potociar_at_oracle.com> wrote:
>> On Oct 12, 2012, at 9:10 AM, Martynas Jusevičius <martynas_at_graphity.org> wrote:
>>
>>> Hey again,
>>>
>>> how can turn a single root resource into a resource factory that
>>> handles all requests through sub-resource locators -- *including* the
>>> base URI @Path("/")?
>>> I tried the following but I get 405 Method not allowed:
>>>
>>> @Path("/")
>>> public class RootResource
>>> {
>>>
>>> @Path("{path: .+}")
>>> public Resource getResource()
>>> {
>>> return new Resource();
>>> }
>>>
>>> }
>>>
>>> I guess Jersey expects @GET etc. on the RootResource -- but I want
>>> @Path("/") to be handled by getResource() as well.
>>> I haven't found any requirements for root resources to contain
>>> resource methods e.g. GET - but maybe @Path("/") is a special case?
>>>
>> Your regular expression seems to require at least one character. Try to replace it with "{path: .*}".
>>
>> Marek
>>
>>
>>> Is this possible with JAX-RS/Jersey?
>>>
>>> I found a very similar dynamic dispatching example in the book
>>> "RESTful Java with JAX-RS" -- however not with the base @Path("/"):
>>>
>>> @Path("/customers")
>>> public class CustomerDatabaseResource {
>>> protected CustomerResource europe = new CustomerResource();
>>> protected FirstLastCustomerResource northamerica =
>>> new FirstLastCustomerResource();
>>> @Path("{database}-db")
>>> public Object getDatabase(@PathParam("database") String db) {
>>> if (db.equals("europe")) {
>>> return europe;
>>> }
>>> else if (db.equals("northamerica")) {
>>> return northamerica;
>>> }
>>> else return null;
>>> }
>>>
>>> Martynas
>>> graphity.org