44

In the web service I'm working on, I need to implement a URI with query parameters which look like /stats?store=A&store=B&item=C&item=D

To break it down, I need to be able to use query parameters to specify data from multiple/all stores and data for multiple/all items from those stores. So far I have been able to implement one query argument just fine in order to pull item data, but I'm lost as far as to how to implement more queries, and can't seem to find the resources I had seen before which deal with this implementation.

What I have so far in my method is along the lines of

@GET
@Path("stats")
public String methodImCalling(@DefaultValue("All") @QueryParam(value = "item") final String item)
{
    /**Run data using item as variable**/
    return someStringOfData
}

which works well for one item, and will return all data if I don't type the parameter in the URI. However, I am unsure how to handle any more parameters than this.

Update:

I have figured out how to use 2 different parameters by simply adding a second argument to the method like so:

public String methodImCalling(@DefaultValue("All") @QueryParam(value = "store") final String store,
    @DefaultValue("All") @QueryParam(value = "item") final String item)

The question remains of how to implement multiple values of the same parameter.

ZKSteffel
  • 1,115
  • 5
  • 13
  • 22

3 Answers3

83

If you change the type of your item method parameter from String to a collection such as List<String>, you should get a collection that holds all the values you are looking for.

@GET
@Path("/foo")
@Produces("text/plain")
public String methodImCalling(@DefaultValue("All") 
                              @QueryParam(value = "item") 
                              final List<String> item) {
   return "values are " + item;
}

The JAX-RS specification (section 3.2) says the following regarding the @QueryParam annotation:

The following types are supported:
  1. Primitive Types
  2. Types that have a constructor that accepts a single String argument.
  3. Types that have a static method named valueOf with a single String argument.
  4. List<T>, Set<T>, or SortedSet<T> where T satisfies 2 or 3 above.
stand
  • 3,054
  • 1
  • 24
  • 27
  • Defining List doesn't work, though. I presume ArrayList will serve the same purpose? – ZKSteffel May 27 '11 at 18:21
  • `List item` didn't work, and `ArrayList item` just broke my code... any other suggestions? – ZKSteffel May 27 '11 at 19:06
  • @ZKSteffel: Not sure why it wouldn't work since I did a quick test and it worked for me. I'll edit my answer to show the full method that I used. Can you give me more information about what failed? – stand May 27 '11 at 19:38
  • 1
    Turns out I imported List from the wrong package, and my code started throwing fits. It's working for me now. Thanks for the help! – ZKSteffel May 27 '11 at 19:56
  • How would you call that if you had a URL? i.e. www.myurl.com/foo?item=listem1&listitem2 – Teivere Nov 22 '11 at 20:12
  • 4
    @Teivere: It would be `www.myurl.com/foo?item=listitem1&item=listitem2` – stand Nov 22 '11 at 23:26
  • I'd double or treble up-vote your answer if I could. I've been Googling for hours! Turns out googling the correct question was important to finding the answer as is usually the case. – the_new_mr Apr 05 '12 at 10:55
9

List<String> items=ui.getQueryParameters().get("item");

where ui is declared as a member in the rest resource like so :

@Context UriInfo ui;

the downside is that it doesn't appear in the methods arguments at all.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
Tal
  • 154
  • 1
  • 4
  • 1
    Although this poster answered the wrong question, it was the question that I googled so I have to upvote it as it helped me. @Tal thanks. – JSager Oct 18 '13 at 20:00
4

Some libs like axios js use the square brackets notation when sending a multi-value param request: /stats?store[]=A&store[]=B&item[]=C&item[]=D

To handle all cases (with or without square brackets) you can add another param like this:

public String methodImCalling(
  @QueryParam(value = "store") final List<String> store, 
  @QueryParam(value = "store[]") final List<String> storeWithBrackets, 
  @QueryParam(value = "item") final List<String> item,
  @QueryParam(value = "item[]") final List<String> itemWithBrackets) {
...
}

Inspecting each of the arguments checking for null.

matias.g.rodriguez
  • 849
  • 11
  • 14