2

I'm comming from the .net world, where if you have an argument like a Dictionary<string,List<string>> foo in the query string, you can do something like foo[one][0]=OneZero,foo[two][0]=TwoZero,foo[two][1]=TwoOne etc. I'd like to have the same in Java Spring (springboot).

I guess the data-type I'm looking for would be either HashMap<String,HashSet<String>> or Map<String,Set<String>>. However I was unable to find a proper solution for this problem. I did managed to make List<String> foo work with foo=one&foo=two or foo=one,two but it seems that using a Map as an argument is unsupported. Is my understanding correct? Is there no out of the box solution for using Maps/Dictionaries (let alone nested ones) as request parameters?

Code

@RestController
public class MyController {

    @GetMapping(value = "/search")
    public PLPResponse getStuff(@RequestParam Optional<String> name, @RequestParam Optional<Map<String,Set<String>> foo, HttpServletRequest request) {
    //magic happens here
    }

}
Hegi
  • 193
  • 2
  • 11
  • 2
    Could you use a json payload or only URL parameters ? – Marged Sep 16 '19 at 19:00
  • 1
    How would `foo[two][1]=TwoOne` map into a `Map>`? Assuming you use `@RequestParam("foo")`, I can see `"two"` being the map key, and `"TwoOne"` being the set value, but what is `"1"` supposed to be? An array index? If so, shouldn't that me mapped into a `Map`? Or a `Map>`, where the index value has meaning? It would be inappropriate to map it into a `Set` like you say, since sets are **unordered**. – Andreas Sep 16 '19 at 19:07
  • Possible duplicate of https://stackoverflow.com/questions/7312436/spring-mvc-how-to-get-all-request-params-in-a-map-in-spring-controller – Chris Belyeu Sep 16 '19 at 19:09
  • @Marged only url query strings are acceptable – Hegi Sep 16 '19 at 19:16
  • @ChrisBelyeu not a duplicate. I am looking for a specific parameter, not all the query strings. Also note the Set/List in my question – Hegi Sep 16 '19 at 19:17
  • @Andreas As you can see my example was for a List. (your assumptions are all correct). I don't care about the order but if this is only feasible with a list, like in C# I will be okay. – Hegi Sep 16 '19 at 19:19
  • Does annotating a method parameter with [`@RequestParam`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html) and using a [`MultiValueMap`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/MultiValueMap.html) as its type solve your problem? – Denis Zavedeev Sep 16 '19 at 19:22
  • I think you might be able to do this by applying your own `WebDataBinder`. See: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-initbinder – Andreas Sep 16 '19 at 19:29
  • @caco3 And how would you use it precisely? Because if I set the type, and try to invoke the method, it throws an error, saying ```No primary or default constructor found for interface org.springframework.util.MultiValueMap``` – Hegi Sep 16 '19 at 19:43
  • Can you share the code of your controller? – Denis Zavedeev Sep 16 '19 at 20:00
  • @caco3 updated post with a sample – Hegi Sep 16 '19 at 20:09
  • Try removing `Optional`: `public PLPResponse getStuff(@RequestParam Optional name, @RequestParam Map> foo, HttpServletRequest request)`. It should wire all parameters into `foo`, but I'm still not sure that it is exactly what you're trying to achieve – Denis Zavedeev Sep 16 '19 at 20:15
  • @caco3 But that's just it. I don't want ALL the parameters in ```foo```. My query has a static part (like filtering by "name") and a dynamic part (let's say by color or by size, or by whatever dynamic attribute is in there). And that dynamic part is - by nature - something which should be collected into a ```Map>``` or something similar. – Hegi Sep 16 '19 at 20:39
  • @Andreas any chance you can share some sample code which works with a ```@RestController```? – Hegi Sep 16 '19 at 20:43
  • @Hegi I don't have any code, hence the "I think..." – Andreas Sep 16 '19 at 20:47

0 Answers0