Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey client: How to add a list as query parameter

Tags:

java

rest

jersey

I'm creating a Jersey client for a GET service that has a List as query parameter. According to the documentation, it's possible to have a List as a query parameter (this information is also at @QueryParam javadoc), check it out:

In general the Java type of the method parameter may:

  1. Be a primitive type;
  2. Have a constructor that accepts a single String argument;
  3. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String)); or
  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.

However, I can't figure out how to add a List query parameter using Jersey client.

I understand alternative solutions are:

  1. Use POST instead of GET;
  2. Transform the List into a JSON string and pass it to the service.

The first one is not good, because the proper HTTP verb for the service is GET. It is a data retrieval operation.

The second will be my option if you can't help me out. :)

I'm also developing the service, so I may change it as needed.

Thanks!

Update

Client code (using json)

Client client = Client.create();  WebResource webResource = client.resource(uri.toString());  SearchWrapper sw = new SearchWrapper(termo, pagina, ordenacao, hits, SEARCH_VIEW, navegadores);  MultivaluedMap<String, String> params = new MultivaluedMapImpl(); params.add("user", user.toUpperCase());  params.add("searchWrapperAsJSON", (new Gson()).toJson(sw));  ClientResponse clientResponse = webResource .path("/listar")                                             .queryParams(params)                                             .header(HttpHeaders.AUTHORIZATION, AuthenticationHelper.getBasicAuthHeader())                                             .get(ClientResponse.class);  SearchResultWrapper busca = clientResponse.getEntity(new GenericType<SearchResultWrapper>() {}); 
like image 460
lsborg Avatar asked Dec 06 '12 18:12

lsborg


People also ask

How do I add a parameter to a query string?

Add a WHERE clause that contains the fields you want to add parameters to. If a WHERE clause already exists, check to see whether the fields you want to add parameters to are already in the clause. If they aren't, add them. Note that you need to add the same filter to each section of the query.

How can I append a query parameter to an existing URL?

This can be done by using the java. net. URI class to construct a new instance using the parts from an existing one, this should ensure it conforms to URI syntax. The query part will either be null or an existing string, so you can decide to append another parameter with & or start a new query.

Can put requests have query parameters?

Is it OK to use query parameters in a PUT request? Absolutely. Query parameters are just another piece of the resource identifier.


2 Answers

@GET does support List of Strings

Setup:
Java : 1.7
Jersey version : 1.9

Resource

@Path("/v1/test") 

Subresource:

// receive List of Strings @GET @Path("/receiveListOfStrings") public Response receiveListOfStrings(@QueryParam("list") final List<String> list){     log.info("receieved list of size="+list.size());     return Response.ok().build(); } 

Jersey testcase

@Test public void testReceiveListOfStrings() throws Exception {     WebResource webResource = resource();     ClientResponse responseMsg = webResource.path("/v1/test/receiveListOfStrings")             .queryParam("list", "one")             .queryParam("list", "two")             .queryParam("list", "three")             .get(ClientResponse.class);     Assert.assertEquals(200, responseMsg.getStatus()); } 
like image 68
Dharmi Avatar answered Oct 21 '22 00:10

Dharmi


If you are sending anything other than simple strings I would recommend using a POST with an appropriate request body, or passing the entire list as an appropriately encoded JSON string. However, with simple strings you just need to append each value to the request URL appropriately and Jersey will deserialize it for you. So given the following example endpoint:

@Path("/service/echo") public class MyServiceImpl {     public MyServiceImpl() {         super();     }      @GET     @Path("/withlist")     @Produces(MediaType.TEXT_PLAIN)     public Response echoInputList(@QueryParam("list") final List<String> inputList) {         return Response.ok(inputList).build();     } } 

Your client would send a request corresponding to:

GET http://example.com/services/echo?list=Hello&list=Stay&list=Goodbye

Which would result in inputList being deserialized to contain the values 'Hello', 'Stay' and 'Goodbye'

like image 33
Perception Avatar answered Oct 21 '22 01:10

Perception