users@jersey.java.net

Re: [Jersey] Dynamic _at_Path

From: Adam Rabung <adamrabung_at_gmail.com>
Date: Thu, 6 Aug 2009 15:32:40 -0400

The @Path("{id: .+}") and URITemplate approach are working well! I
moved static resources to /static so these don't collide, and that
seems to be working too.

Is it fair to say that if a traditional resource declares
@Path("/widgets"), and a client requests
/widgets/hammer/widgetsInNeedOfRepair, the generic Resource will _not_
be able to respond? In my experience, requests that extend on a root
from a traditional resource result in a 404, rather than pass through
to the generic resource.

In other words, it seems I cannot serve "/widgets" from a traditional
resource and "/widgets/hammer" from the generic source side-by-side.
Can I use a filter perhaps to ensure these types of requests make it
to the generic resource?

Thanks,
Adam


On Thu, Aug 6, 2009 at 2:44 PM, Paul Sandoz<Paul.Sandoz_at_sun.com> wrote:
>
> On Aug 6, 2009, at 5:40 PM, Adam Rabung wrote:
>
>> Hello,
>> First off, I am loving Jersey!  I'm finding it very intuitive and
>> clean to write my resources/providers.  Keep up the good work.
>>
>
> Thanks!
>
> What you require is currently not supported, but i think it would be fairly
> easy to add to Jersey. Let me work on it. Note that matching only happens on
> the path and not query parameters, so you would need to consume query
> parameters separately using @QueryParam or by getting the multivalued map
> from UriInfo.
>
> One possible solution you can try at the moment is to use @Path("{path:
> .+}") and UriTemplate [1]. For example:
>
>  @Path("{id: .+}")
>  @GET
>  public ... get(@PathParam("id") String id) {
>    UriTemplate t = new
> UriTemplate("widgets/{widgetType}/widgetsInNeedOfRepair");
>
>    Map<java.lang.String,java.lang.String> nameValues = ...
>    if (t.match(id, nameVaues)) {
>      ...
>    } else {
>      throw new WebApplicatonException(404);
>    }
>  }
>
> I think for static file serving you may require a filter that checks if the
> URL points to a static file, if so that file is returned otherwise
> processing continues. For this you can use a Jersey container filter or a
> Servlet filter.
>
> Paul.
>
> [1]
> https://jersey.dev.java.net/nonav/apidocs/1.1.1-ea/jersey/com/sun/jersey/api/uri/UriTemplate.html
>
>
>> My application has 5-10 "standard" rest resources that lend themselves
>> well to the class/method annotation style of Jersey.  However, several
>> more resources are essentially defined externally.  Think of these as
>> XML reports which define the url they want to publish to:
>> Report #1:
>> <resource url = "/widgets/{widgetType}/widgetsInNeedOfRepair">
>> .... DSL describing how to execute the query
>> <resource>
>>
>> Report #2:
>> <resource url =
>>
>> "/company/{company}/people/{department}/peopleWithExcessVacationTime?employeeType=manager">
>> .... DSL describing how to execute the query
>> <resource>
>>
>> These reports can be executed by the same generic Resource class, but
>> many different Paths need to match this generic class.  My goal is to
>> allow this generic Resource to take advantage of other annotations
>> (Produces, GET, etc) and all of the other Jersey resources such as
>> Providers.
>>
>> I found a recommendation to use
>> @Path("{fullPath}")
>> I can then use UriInfo#getPathParameters to inspect what was passed in
>> and glean out the path Parameters.  I only have two problems w/ this
>> approach:
>> 1. As far as I can tell, I'd need a method for each number of
>> anticipated path elements:
>>        @GET
>>        public Iterable<ExportNode> executeQuery1(@Context UriInfo ui) {
>>                return executeQuery(ui);
>>        }
>>
>>        @GET
>>        @Path("/{param1}")
>>        public Iterable<ExportNode> executeQuery2(@Context UriInfo ui) {
>>                return executeQuery(ui);
>>        }
>>
>>        @Path("/{param1}/{param2}")
>>        @GET
>>        public Iterable<ExportNode> executeQuery3(@Context UriInfo ui) {
>>                return executeQuery(ui);
>>        }
>>       etc etc
>>
>> 2. It seems this all-encompassing URL matching would cause problems
>> for static file serving.
>>
>> I'm so new to Jersey and even Rest that I'm sure I'm taking a
>> completely wrong approach here, but I think my "dream" code would be:
>>
>> ... at startup:
>> jersey.registerResource("/widgets/{widgetType}/widgetsInNeedOfRepair",
>> GenericResource.class);
>>
>> jersey.registerResource("/company/{company}/people/{department}/peopleWithExcessVacationTime?employeeType=manager",
>> GenericResource.class);
>> ...and Generic Resource:
>> @Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
>> public class GenericResource {
>>        @GET
>>        public ReportResult executeQuery(@Context UriInfo ui) {
>>                //use UriInfo to figure out exactly which report they are
>> invoking,
>> and what the parameters are
>>        }
>> }
>>
>> What's the right approach for a problem like this?  Any input is much
>> appreciated.
>>
>> Thanks,
>> Adam
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>