users@jersey.java.net

[Jersey] Re: Sub-resource addressed by only one path segment?

From: Miroslav Fuksa <miroslav.fuksa_at_oracle.com>
Date: Tue, 11 Jun 2013 09:56:22 +0200

Hi Jim,

which Jersey version you are using?

In Jersey 2 this should be possible, you can have sub resource locators
with empty path:

     @Path("/")
     public EntityCollectionsListResource get() {
         return listResourceFactory.createForCommunityListContext();
     }

In Jersey 1.x this looks like such a construction does not work. Your
sub resource locator method is not even called when it has empty path.

So, if you use Jersey 1, you might implement something like this:

@Path("/community-list")
public static class CommunityListResource {
     ....

     @GET
     public String get() {
         return ....
     }

     @Path("{id}/list")
     public CommunityListResource locator() {
         // here check the UriInfo.getMatchedURIs() and if we are
already in /community-list/{id}/list throw
         // WebApplicationException with 404 code.


         return listResourceFactory.createForCommunityListContext();
     }

}

So, you would return the same class from the sub resource locator and if
you are already in "sub resource" then return 404 by
WebApplicationException. I am not saying this is nice solution but could
help.

Mira

On 06/11/2013 01:17 AM, Jim Danz wrote:
> Hi folks,
>
> I am wondering if I can have a sub-resource with only one path segment.
>
> Specifically, I am trying to have a scheme where there is a
> subresource EntityCollectionsListResource that is listening on:
> /user/{id}/list
> and
> /community-list
>
> I was able to wire the /user/{id}/list portion of this without trouble.
> I'm having trouble with the community-list portion.
>
> My community list resource looks like:
> @Path("/community-list")
> public class CommunityListResource {
> private final EntityCollectionsListResourceFactory listResourceFactory;
>
> @Inject
> CommunityListResource(EntityCollectionsListResourceFactory
> listResourceFactory) {
> this.listResourceFactory = listResourceFactory;
> }
>
> @Path("/")
> public EntityCollectionsListResource get() {
> return listResourceFactory.createForCommunityListContext();
> }
> }
>
> Where EntityCollectionsListResource has, among other things:
> @PUT
> @GET
> @Path("/{listIdentifierParam}") @GET
>
> The subpaths in EntityCollectionsListResource work fine. For instance,
> GET /community-list/Foo
> ==> 200
>
> But a plain
> GET /community-list
> ==> 405
>
> And likewise:
> GET /community-list/
> ==> 405
>
> I've stepped through the debugger, and it looks like "/community-list"
> alone doesn't even get to the EntityCollectionsListResource. It gets
> stuck at the CommunityListResource, in that the after match
> "/community-list" it has only empty string remaining in path, and then
> it refuses to match on "/".
>
> So, I'd like to ask: is there any way to have a subresource with only
> a single path statement that addresses it? I can change
> CommunityListResource to the following:
> @Path("/community-list")
> public class CommunityListResource {
> private final EntityCollectionsListResourceFactory listResourceFactory;
>
> @Inject
> CommunityListResource(EntityCollectionsListResourceFactory
> listResourceFactory) {
> this.listResourceFactory = listResourceFactory;
> }
>
> @Path("/community-list")
> public EntityCollectionsListResource get() {
> return listResourceFactory.createForCommunityListContext();
> }
> }
>
> And everything works fine on /community-list/community-list, but it's
> not the URL structure that I'd hoped for.
>
> Many thanks,
> Jim