226

Sample URL:

../search/?attr1=value1&attr2=value2&attr4=value4

I do not know the names of attr1, att2, and attr4.

I would like to be able to do something like that (or similar, don't care, just as long as I have access to the Map of request param name -> value:

@RequestMapping(value = "/search/{parameters}", method = RequestMethod.GET)
public void search(HttpServletRequest request, 
@PathVariable Map<String,String> allRequestParams, ModelMap model)
throws Exception {//TODO: implement}

How can I achieve this with Spring MVC?

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
MDb
  • 2,261
  • 2
  • 14
  • 3

10 Answers10

356

While the other answers are correct it certainly is not the "Spring way" to use the HttpServletRequest object directly. The answer is actually quite simple and what you would expect if you're familiar with Spring MVC.

@RequestMapping(value = {"/search/", "/search"}, method = RequestMethod.GET)
public String search(
@RequestParam Map<String,String> allRequestParams, ModelMap model) {
   return "viewName";
}
Adam Gent
  • 47,843
  • 23
  • 153
  • 203
37

Edit

It has been pointed out that there exists (at least as of 3.0) a pure Spring MVC mechanism by which one could get this data. I will not detail it here, as it is the answer of another user. See @AdamGent's answer for details, and don't forget to upvote it.

In the Spring 3.2 documentation this mechanism is mentioned on both the RequestMapping JavaDoc page and the RequestParam JavaDoc page, but prior, it is only mentioned in the RequestMapping page. In 2.5 documentation there is no mention of this mechanism.

This is likely the preferred approach for most developers as it removes (at least this) binding to the HttpServletRequest object defined by the servlet-api jar.

/Edit

You should have access to the requests query string via request.getQueryString().

In addition to getQueryString, the query parameters can also be retrieved from request.getParameterMap() as a Map.

Community
  • 1
  • 1
nicholas.hauschild
  • 42,483
  • 9
  • 127
  • 120
  • 14
    I suspect someone downvoted this answer just because getQueryString returns a String and not a Map. The op was looking for a Map of parameters. I added getParameterMap to your answer to help make it more correct :) +1 – jamesmortensen Jan 19 '12 at 01:50
  • No I downvoted because its not the Spring MVC way to do it. `@RequestParam` will gladly take a `Map` as a parameter (see my answer). – Adam Gent Aug 28 '13 at 13:21
  • @AdamGent The question was asked at a time when Spring 3.2 was not yet released. Go back and take a look at the JavaDoc for 3.1, and you will notice there is no such mention of utilizing `@RequestParam` on a `Map` to retrieve all query string parameters. And please, don't feel ***so*** abhorred over the answers you see here...they aren't ***that*** bad :) http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html – nicholas.hauschild Aug 28 '13 at 13:39
  • I think it existed in 3.1 but was not JavaDoced. I didn't say I was *abhorred* but shocked that the `@RequestParam Map<>` way was not done. I have slight annoyance in that many modern projects I have seen Spring MVC (spring 3.1 and greater) they will put the HttpServletRequest and HttpServletResponse on every method. And it seems its because junior developers use StackOverflow and google instead of looking at the doc. This makes it difficult for the Spring project to switch from servlet api to say a Netty API. JAX-RS has similar issues of abuse but at a far lesser degree. – Adam Gent Aug 28 '13 at 16:34
  • 1
    And it is [JavaDoced in 3.1](http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html) just not in all the right places: "*Additionally, @RequestParam can be used on a Map or MultiValueMap method parameter to gain access to all request parameters.*". Infact it goes all the way back to version 3.0 (I knew I used it before 3.1). My annoyance still stands in that people didn't bother doing the research :) – Adam Gent Aug 28 '13 at 16:43
  • @AdamGent Fair enough. I prefer the way it was documented in 3.2, as it seems a bit more clear. Post edit inbounds. – nicholas.hauschild Aug 28 '13 at 18:01
18

Here's a simple example of getting requestParams in a Map:

@RequestMapping(value="submitForm.html", method=RequestMethod.POST)
public ModelAndView submitForm(@RequestParam Map<String, String> reqParam) {
    String name  = reqParam.get("studentName");
    String email = reqParam.get("studentEmail");     
    ModelAndView model = new ModelAndView("AdmissionSuccess");
    model.addObject("msg", "Details submitted by you::Name: " + name
                                                + ", Email: " + email );
}

In this case, it will bind the values:

  • studentName with name
  • studentEmail with email
ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
Shrirang Kadale
  • 472
  • 1
  • 4
  • 16
  • 2
    I really like this answer but Map seems to have a problem because it is possible that some parameters have multiple values. I guess Map or so makes more sense. – Natan Cox Nov 05 '20 at 15:55
14

The HttpServletRequest object provides a map of parameters already. See request.getParameterMap() for more details.

jamesmortensen
  • 33,636
  • 11
  • 99
  • 120
Kevin
  • 24,871
  • 19
  • 102
  • 158
  • 1
    Get parameter map will also contain form data from a POST request. If the user does not know the keys in the query string, then how will they be able to distinguish between what came from the query string and what is from data from a POST body? – nicholas.hauschild Sep 05 '11 at 22:26
  • Are you telling me you're going to process a form post but you have no idea what the actual form parameters are? – Kevin Sep 06 '11 at 00:07
  • 2
    The question states that he doesn't know what the parameter names are. Also, I do not know what they are either. ;) – nicholas.hauschild Sep 06 '11 at 00:14
  • Sorry I find the premise a bit ridiculous. – Kevin Sep 06 '11 at 00:56
  • 11
    It makes sense in a data driven application. One where request paths and query strings can be made up by the client, and the application server would then look up the corresponding value (from any sort of datasource) by using these paths and query strings as keys. – nicholas.hauschild Sep 06 '11 at 01:20
  • [similar SO question to iterate through the map without knowing any key names](http://stackoverflow.com/questions/1066589/iterate-through-a-hashmap) – Don Cheadle Mar 13 '15 at 14:08
  • @Kevin, i don't find it ridiculous. You cannot always be certain the fields are fixed. Sooner or later, you have to gonna interrogate the fields there... – daparic Jan 06 '18 at 09:11
  • You have to know parameters you are getting or in case of data driven application, you have to know what you are looking up. If you don't know either, you can only pass the received collection of parameters, to some other method, which knows what to look up. – tapasvi Jan 23 '18 at 21:04
  • I don't find it ridiculous that you wouldn't know the keys. However, I do find it ridiculous that handling of POST parameters and GET parameters should be any different. Why should it matter which ones they are? – eis Sep 18 '19 at 13:32
12

you can simply use this:

Map<String, String[]> parameters = request.getParameterMap();

That should work fine

Biggy_java
  • 455
  • 1
  • 4
  • 16
8

There are two interfaces

  1. org.springframework.web.context.request.WebRequest
  2. org.springframework.web.context.request.NativeWebRequest

Allows for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API.

Ex.:

@RequestMapping(value = "/", method = GET)
public List<T> getAll(WebRequest webRequest){
    Map<String, String[]> params = webRequest.getParameterMap();
    //...
}

P.S. There are Docs about arguments which can be used as Controller params.

Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90
katoquro
  • 326
  • 3
  • 9
  • Thank you it works. May I ask, what's the point of `String[]` as the value? I have to index it to 0 just to get the value. – daparic Jan 06 '18 at 09:07
  • There can be an array of values like `key=val1,val2` or `key=val1&key=val2` (if I remember correctly spring support both of these notations) so you will get array with 2 elements – katoquro Jan 10 '18 at 12:48
8

Use org.springframework.web.context.request.WebRequest as a parameter in your controller method, it provides the method getParameterMap(), the advantage is that you do not tight your application to the Servlet API, the WebRequest is a example of JavaEE pattern Context Object.

Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90
6

I might be late to the party, but as per my understanding , you're looking for something like this :

for(String params : Collections.list(httpServletRequest.getParameterNames())) {
    // Whatever you want to do with your map
    // Key : params
    // Value : httpServletRequest.getParameter(params)                
}
buræquete
  • 14,226
  • 4
  • 44
  • 89
goelanshul
  • 61
  • 1
  • 2
2
@SuppressWarnings("unchecked")
Map<String,String[]> requestMapper=request.getParameterMap();
JsonObject jsonObject=new JsonObject();
for(String key:requestMapper.keySet()){
    jsonObject.addProperty(key, requestMapper.get(key)[0]);
}

All params will be stored in jsonObject.

Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
0

There is fundamental difference between query parameters and path parameters. It goes like this: www.your_domain?queryparam1=1&queryparam2=2 - query parameters. www.your_domain/path_param1/entity/path_param2 - path parameters.

What I found surprising is that in Spring MVC world a lot of people confuse one for the other. While query parameters are more like criteria for a search, path params will most likely uniquely identify a resource. Having said that, it doesn't mean that you can't have multiple path parameters in your URI, because the resource structure can be nested. For example, let's say you need a specific car resource of a specific person:

www.my_site/customer/15/car/2 - looking for a second car of a 15th customer.

What would be a usecase to put all path parameters into a map? Path parameters don't have a "key" when you look at a URI itself, those keys inside the map would be taken from your @Mapping annotation, for example:

@GetMapping("/booking/{param1}/{param2}")

From HTTP/REST perspective path parameters can't be projected onto a map really. It's all about Spring's flexibility and their desire to accommodate any developers whim, in my opinion.

I would never use a map for path parameters, but it can be quite useful for query parameters.

yuranos
  • 8,799
  • 9
  • 56
  • 65