users@jersey.java.net

Re: [Jersey] Transforming paths via filter

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 04 Nov 2008 11:13:25 +0100

On Nov 3, 2008, at 9:56 PM, Tim Pesce wrote:

> On Nov 3, 2008, at 1:02 PM, Paul Sandoz wrote:
>
>> Hi Tim,
>>
>> On Nov 3, 2008, at 8:34 PM, Tim Pesce wrote:
>>
>>> I have a scenario where I'd like to extract a path parameter into
>>> a query parameter. So URIs of the form:
>>>
>>> /context/scope/{scopeid}/resource
>>>
>>> would become:
>>>
>>> /context/resource?scope=scopeid
>>>
>>> My initial approach was to create a ContainerRequestFilter and
>>> modify the request's URIs via ContainerRequest.setUris(). However,
>>> this approach does not seem viable because the path is calculated
>>> prior to filter invocation (from
>>> WebApplicationImpl._handleRequest()):
>>>
>>
>> Drat, that is a bug. The path needs to be obtained after filters
>> have been applied. Also the request filter can return a new request
>> so that needs to be catered for as well. Could you log an issue?
>>
>
> Will do!
>

Thanks,


>>>
>>> My new plan is to perform this transformation via Servlet filter,
>>> but given the earlier discussion around per-resource filters and
>>> issue #134 I'm wondering if this use case may be something that
>>> Jersey can more directly support in the future. Also more
>>> generally, are there better approaches for handling this scenario
>>> within Jersey?
>>>
>>
>> You can do it explicitly with resource classes and reuse code:
>>
>> @Path("content")
>> public class ResourceContext {
>> @Path("scope/{scopeid}/resource"
>> @GET
>> ... getAsPath(@PathParam("scopeid") String scope) {
>> return getAsQuery(scope);
>> }
>>
>> @Path("resource")
>> @GET
>> ... getAsQuery(@QueryParam("scope") Scope scope) { ... }
>> }
>>
>> I suspect that is not what you want.
>>
>> Like Jeff i am curious as to why you want to do this to understand
>> your use-case better.
>>
>
> As you and Jeff point out, dealing with this kind of situation in
> general is really easy with JAX-RS, and this is one of the reasons
> I've been really fond of working with it (and Jersey!). My use case
> is related to deployment requirements and more specifically the
> ability to match differing URL conventions for different but related
> applications.
>
> In all cases there is the concept of a scope at the resource level.
> In some applications the scope is variable and supplied as a path
> parameter, while in others the scope has an implied default (not
> specified via URL). Furthermore, different applications have
> different "prefix" components for the scope (e.g. /container/
> {scopeid}, /folder/{scopeid}) and there may be a need to provide
> valid resources only if the application-specific prefix was used.
>

It seems to me that you want to use a query parameter to support a
default value, is that correct?

Why don't you use a special value for the default scope e.g.:

   /folder/default
   /folder/{scopeid}

You can match such things explicitly with JAX-RS or you can check the
@PathParam value yourself.

Or just support:

   /folder <- the default scope, no q param
required, it is implied
   /folder/{scopeid}

i.e. if you put the scope after the thing you are talking about it
might make it easier to support. But it is hard for me to say really
what you need because i don't fully understand your requirements.

One issue with this is HTML forms are restricted in terms of the URL
that is created, they cannot construct a path from say a URI template.
So one has to use JavaScript, or use query parameters. Ideally query
parameters should be used to restrict the information returned in a
representation and should not be relied

Paul.

> I'm trying to keep the resource classes simple by decoupling the
> scope mapping issues, and my original thoughts were around providing
> application-specific filters. I hadn't thought of your "getAsPath"
> suggestion, though in my case I'm not sure it would be quite as
> clean as I'd like. In my original example "/context" was intended to
> be the baseURI of the request, so I'd need to map both scoped and
> non-scoped paths to the same logical root resource. I'll have to dig
> into this more; I may be able to do what I want by using simple
> application-specific root resources instead of filters.
>
>