14

Is there a way to use this parameter style:

/products/123;456;789

in JAX-RS with Jersey? If I use PathParam, only the first parameter in the list is returned. I tried to escape the semicolon but then Jersey returns only "123;456;789" as the value of the first parameter list entry

I declared the GET method as

public List<Product> getClichedMessage(@PathParam("ids") List<String> idList)

Update: I am referring to the Jersey user guide for Jersey 1.1.5:

In general the Java type of the method parameter may (...) 4) be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only. (...) Sometimes parameters may contain more than one value for the same name. If this is the case then types in 4) may be used to obtain all values.

Update: here is my test code:

package de.betabeans.resources;

import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/test")
public class TestResource {

    @GET
    @Path("/{ids}")
    @Produces({"text/plain"})
    public String getClichedMessage(@PathParam("ids") List<String> idList) {
        return "size=" + idList.size();
    }

}

Test URL with semicolon escaped: http://localhost:8080/resources/test/1%3B2%3B3

Update: the changelog for Jersey 1.3 include this information:

Fixed issue 540
http://java.net/jira/browse/JERSEY-540 Parameterized types of List/Set/SortedSet are supported for parameters, for example @QueryParam("d") List>, if there is a StringReaderProvider registered that supports the type List.

I'll check out StringReaderProvider based on this post http://comments.gmane.org/gmane.comp.java.jersey.user/7545

mjn
  • 36,362
  • 28
  • 176
  • 378
  • About the second update: Sorry, but you are not going to succeed this way. You continue to use matrix parameters, while you think that the semicolon is a separator for path parameters. It is not. And it's not going to become one. It's separator for matrix parameters, to create urls like /moremaps.com/map/color;lat=50;long=20;scale=32000 – Tarlog Apr 01 '11 at 14:10

1 Answers1

23

When you use semicolon, you create Matrix parameters. You can use either @MatrixParam or PathSegment to get them. Example:

 public String get(@PathParam("param") PathSegment pathSegment)

Pay attention that Matrix parameters are these that follow the original parameter. So in case of "123;456;789" - 123 is path parameter, while 456 and 789 are the names of matrix parameters.

So if you want to get products by ids, you can do something like this:

public List<Product> getClichedMessage(@PathParam("ids") PathSegment pathSegment) {
    Set<String> ids = pathSegment.getMatrixParameters().keySet();
    // continue coding
}

Pay attention that your url should be /products/ids;123;456;789

Actually, IMO it is not a very good design: you use matrix parameter name as a value. I think using query parameters is better: /products?id=123&id=456&id=789, so you can easily get them in method:

public List<Product> getClichedMessage(@QueryParam("id") List<String> ids)
Tarlog
  • 10,024
  • 2
  • 43
  • 67
  • 1
    Thank you for this suggestion! See my update, in the documentation it seems like PathParam actually supports multiple values too. – mjn Apr 01 '11 at 13:34
  • Well, it's partially true. You can write something like @Path("/url/{param}/and/{param}) so @PathParam will be duplicated and it can be received as a list. But I don't think its what you want. – Tarlog Apr 01 '11 at 13:47
  • Yes this works, but then the number of parameters in the URL must match exactly the number in the pattern. My workaround was is to use String instead of List and do the parsing in code (String.split(ids)). – mjn Apr 01 '11 at 14:08
  • Well, it's obvious that your workaround will work. You get the whole path segment and parse it yourself. This way you can use anything as a separator and it will work. Just pay attention that it is not very RESTful, since you use predefined conventions in a bit different way then you supposed to use them. – Tarlog Apr 01 '11 at 14:18
  • Ok, I'll check out the /products?id=123&id=456&id=789 style then (didn't know parameters can appear multiple times). Actually the semicolon-separated parameter is used in the Stackoverflow API (see http://api.stackoverflow.com/1.1/usage/methods/users-by-ids) – mjn Apr 01 '11 at 14:54
  • Well, may be they don't know that semicolon is used in matrix URIs... :) My point was that if you decide to use a propriety separator, which is ok, don't use semicolon, since it's used for matrix parameters. Use something else. – Tarlog Apr 01 '11 at 15:22
  • Thanks @Tarlog I confirm that your suggestion works in restEasy also. – kiran.kumar M Apr 15 '11 at 05:11