users@jersey.java.net

Re: [Jersey] Example of matrix URIs?

From: Gili <cowwoc_at_bbs.darktech.org>
Date: Mon, 29 Dec 2008 09:28:21 -0800 (PST)

My code defines two methods:

@GET
@Path("{ids}")
public String selectThemes(@PathParam("ids") String ids,
@QueryParam("select") String select);

and

@Path("{id}")
public ThemeResource locateTheme(@PathParam("id") long id);

I was expecting Jersey to select the 1st one if the user specifies a
"select" query parameter and the 2nd one if he does not. Instead, Jersey
always selects the first one. This is problematic because I can't see an
easy way to pass Jersey a sub-resources if "select" is null. I can't chain
the method calls by invoking locateTheme() because the return types are
different and I'd rather not have to invoke locateTheme().get() on behalf of
Jersey. What does the JAX-RS standard say about this? Couldn't we improve
Jersey's handling in this case?

Thanks,
Gili


Gili wrote:
>
> What about if I provide a "more specific" match for JAX-RS (as follows)?
> Will it be smart enough to pick this instead of the sub-resource?
>
> @GET
> @Path("{ids}")
> @Produces(MediaType.APPLICATION_XML)
> public String selectThemes(@PathParam("ids") String ids,
> @QueryParam("select") String select)
>
> I would then discard the "select" String and use "ids" instead.
>
> Gili
>
>
> Gili wrote:
>>
>>
>> Here are some real URIs I have mapped.
>>
>> POST /themes to create an image theme (a theme is like a category)
>>
>> GET /themes/{id} to retrieve the theme state
>>
>> GET /themes/{id};{id};{id}?select=randomImages to select random images
>> from a set of image themes
>>
>> In other words, /theme/{id} might return the theme name whereas
>> /theme/1;2;3?select=randomImages would generate a set of all the images
>> that fall under themes 1, 2 and 3 then return X random images from that
>> pool.
>>
>> Here is what I currently have:
>>
>> @Path("themes")
>> class ThemesResource
>> {
>> /**
>> * Returns the Theme sub-resource.
>> */
>> @Path("id")
>> public ThemeResource locateTheme(@PathParam("id") long id);
>> }
>>
>> and now I want to add:
>>
>> /**
>> * Returns the Theme sub-resource.
>> */
>> @Path("id")
>> public String selectRandomImages(@PathParam("id") String listOfIds);
>>
>> I don't think that @Path("{images: [\d,]+"} would help because
>> locateTheme is supposed to match exactly one id so there would be an
>> overlap. In fact, "/themes/5?select=randomImages" is perfectly legal and
>> should not return a sub-resource.
>>
>> Gili
>>
>> Paul Sandoz (via Nabble) wrote:
>>>
>>> On Nov 11, 2008, at 7:31 PM, Gili wrote:
>>>
>>> >
>>> > Sorry, I forgot to mention... For:
>>> >
>>> > http://example.com/images/1;2;5?select=random
>>> >
>>> > I already have a sub-resource that matches @Path("{id}").
>>>
>>> For what path segment the image ids "1;2;5" ?
>>>
>>> > This means that I
>>> > want one method returning a sub-resource (the "Image" resource), and
>>> > another
>>> > method returning an XML document (the list of random images). In
>>> other
>>> > words, the method return-type varies based on the query string.
>>> >
>>> > Is there a way for me to configure JAX-RS to pick the right method
>>> > somehow?
>>> > What do you recommend?
>>> >
>>>
>>> I recommend you use a comma separated list of image ids as it works
>>> better for path matching. You could have "random" as part of the path
>>> too:
>>>
>>> @Path("{images: [\d,]+"}
>>> public class ImagesResource {
>>> @PathParam("images") IntegerList images;
>>>
>>> @Path("random")
>>> @GET
>>> public ... get() {
>>> }
>>>
>>> @GET
>>> }
>>>
>>> If you use a query parameter then you have to do some checking of the
>>> values yourself.
>>>
>>> It would help me if you could present some code of how you are
>>> componentizing things as i might be able to help you better. Or break
>>> down and present the different URIs you want to support.
>>>
>>> Paul.
>>>
>>> > Thanks,
>>> > Gili
>>> >
>>> >
>>> >
>>> > Gili wrote:
>>> >>
>>> >> Paul,
>>> >>
>>> >> Does @Path ignore query arguments? If I want to parse for:
>>> >>
>>> >> http://example.com/images/1;2;5?select=random
>>> >>
>>> >> Can I use the following?
>>> >>
>>> >> @Path("{id}?select=random")
>>> >>
>>> >> or would I be forced to use a single method and fork execution
>>> myself
>>> >> based on the query arguments?
>>> >>
>>> >> Thanks,
>>> >> Gili
>>> >>
>>> >>
>>> >> Paul Sandoz wrote:
>>> >>>
>>> >>>
>>> >>> On Nov 10, 2008, at 10:40 PM, Gili wrote:
>>> >>>
>>> >>>>
>>> >>>>
>>> >>>> Paul Sandoz wrote:
>>> >>>>>
>>> >>>>> A better use would be:
>>> >>>>>
>>> >>>>> http://example.com/images;1;2;5/tags
>>> >>>>>
>>> >>>>> as then the matrix parameters are associated with a named path
>>> >>>>> segment. Matrix parameters are ignored when path matching. The
>>> >>>>> best
>>> >>>>> way to think about them is as query parameters scoped to a path
>>> >>>>> segment.
>>> >>>>>
>>> >>>>
>>> >>>> I don't understand how the above would work. Are you saying that
>>> >>>> "images"
>>> >>>> would have 3 matrix parameters: 1, 2 and 5?
>>> >>>
>>> >>> Yes, specifically there are three matrix parameter names, each of
>>> >>> which has no value.
>>> >>>
>>> >>>
>>> >>>> Paul Sandoz wrote:
>>
>>> >>>
>>> >>>>>
>>> >>>>> If you are using the path segment matching approach you could do:
>>> >>>>>
>>> >>>>> @GET_at_Path("images/{id: <regex for digits and commas>}/tags")
>>> >>>>> public ... get(@PathParam("id") ImageList images) { ... }
>>> >>>>>
>>> >>>>> and the class ImageList has a string constructor that parses the
>>> >>>>> comma
>>> >>>>> separated list of names (see the Sparklines sample [1]).
>>> >>>>>
>>> >>>>
>>> >>>> Okay, I just wanted to get back a List<Integer>. I guess I could
>>> >>>> code this
>>> >>>> up myself.
>>> >>>
>>> >>> You could only do that with @MatrixParam (or @QueryParam) if you
>>> >>> have
>>> >>> one or more matrix parameters with the same name. You can use the
>>> >>> following class for any @*Param value:
>>> >>>
>>> >>> public class IntegerList extends ArrayList<Integer> {
>>> >>> public IntegerList(String s) {
>>> >>> super();
>>> >>>
>>> >>> for (String v : s.split(",")) {
>>> >>> try {
>>> >>> add(Integer.parseInt(v.trim()));
>>> >>> } catch (Exception ex) {
>>> >>> throw new WebApplicationException(400);
>>> >>> }
>>> >>> }
>>> >>> if (isEmpty())
>>> >>> throw new WebApplicationException(400);
>>> >>> }
>>> >>> }
>>> >>>
>>> >>> Paul.
>>> >>>
>>> >>>
>>> ---------------------------------------------------------------------
>>> >>> To unsubscribe, e-mail: users-unsubscribe@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=0>
>>> >>> For additional commands, e-mail: users-help@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=1>
>>> >>>
>>> >>>
>>> >>>
>>> >>
>>> >>
>>> >
>>> > --
>>> > View this message in context:
>>> http://n2.nabble.com/Example-of-matrix-URIs--tp1482069p1486308.html
>>> > Sent from the Jersey mailing list archive at Nabble.com.
>>> >
>>> >
>>> > ---------------------------------------------------------------------
>>> > To unsubscribe, e-mail: users-unsubscribe@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=2>
>>> > For additional commands, e-mail: users-help@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=3>
>>> >
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=4>
>>> For additional commands, e-mail: users-help@...
>>> <http://n2.nabble.com/user/SendEmail.jtp?type=node&node=1486388&i=5>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>> This email is a reply to your post @
>>> http://n2.nabble.com/Example-of-matrix-URIs--tp1482069p1486388.html
>>> You can reply by email or by visting the link above.
>>>
>>
>>
>
>

-- 
View this message in context: http://n2.nabble.com/Example-of-matrix-URIs--tp1482069p2089529.html
Sent from the Jersey mailing list archive at Nabble.com.