I have the following method in my Spring MVC @Controller :
@RequestMapping(method = RequestMethod.GET)
public String testUrl(@RequestParam(value="test") Map<String, String> test) {
(...)
}
I call it like this :
http://myUrl?test[A]=ABC&test[B]=DEF
However the "test" RequestParam variable is always null
What do I have to do in order to populate "test" variable ?
I faced a similar situation where the client sends two groups of variable parameters. Let's call these groups foo
and bar
. A request could look like:
GET /search?page=2&size=10&foo[x]=aaa&foo[y]=bbb&bar[z]=ccc
I wanted to map these parameters to two distinct maps. Something like:
@GetMapping("/search")
public Page<...> search(Pageable pageable,
@RequestParam(...) Map<String, String> foo,
@RequestParam(...) Map<String, String> bar) {
...
}
@RequestParam
didn't work for me, too. Instead I created a Model class with two fields of type Map<>
matching the query parameter names foo
and bar
(@Data
is lombok.Data
).
@Data
public static class FooBar {
Map<String, String> foo;
Map<String, String> bar;
}
My controller code has changed to:
@GetMapping("/search")
public Page<...> search(Pageable pageable, FooBar fooBar) {
...
}
When requesting GET /search?page=2&size=10&foo[x]=aaa&foo[y]=bbb&bar[z]=ccc
Spring instantiated the Maps and filled fooBar.getFoo()
with keys/values x
/aaa
and y
/bbb
and fooBar.getBar()
with z
/ccc
.
You can create a new class that contains the map that should be populated by Spring and then use that class as a parameter of your @RequestMapping
annotated method.
In your example create a new class
public static class Form {
private Map<String, String> test;
// getters and setters
}
Then you can use Form
as a parameter in your method.
@RequestMapping(method = RequestMethod.GET)
public String testUrl(Form form) {
// use values from form.getTest()
}
As detailed here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
If the method parameter is Map or MultiValueMap and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.
So you would change your definition like this.
@RequestMapping(method = RequestMethod.GET)
public String testUrl(@RequestParam Map<String, String> parameters)
{
(...)
}
And in your parameters if you called the url http://myUrl?A=ABC&B=DEF
You would have in your method
parameters.get("A");
parameters.get("B");
Spring doesn't have default conversion strategy from multiple parameters with the same name to HashMap. It can, however, convert them easily to List, array or Set.
@RequestMapping(value = "/testset", method = RequestMethod.GET)
public String testSet(@RequestParam(value = "test") Set<String> test) {
return "success";
}
I tested with postman like http://localhost:8080/mappings/testset?test=ABC&test=DEF
You will see set having data, [ABC, DEF]
Your question needs to be considered from different points of view.
as is mentioned in the title of the question, is how to have Map<String, String>
as @RequestParam
.
Consider this endpoint:
@GetMapping(value = "/map")
public ResponseEntity getData(@RequestParam Map<String, String> allParams) {
String str = Optional.ofNullable(allParams.get("first")).orElse(null);
return ResponseEntity.ok(str);
}
you can call that via:
http://<ip>:<port>/child/map?first=data1&second=data2
then when you debug your code, you will get these values:
> allParams (size = 2)
> first = data1
> second = data2
and the response of the requested url will be data1
.
as your requested url shows (you have also said that in other answers' comments) ,you need an array
to be passed by url.
consider this endpoint:
public ResponseEntity<?> getData (@RequestParam("test") Long[] testId,
@RequestParam("notTest") Long notTestId)
to call this API and pass proper values, you need to pass parameters in this way:
?test=1&test=2¬Test=3
all test
values are reachable via test[0]
or test[1]
in your code.
have another look on requested url parameters, like: test[B]
putting brackets
(or [
]
) into url is not usually possible. you have to put equivalent ASCII
code with %
sign.
for example [
is equal to %5B
and ]
is equal to %5D
.
as an example, test[0]
would be test%5B0%5D
.
more ASCII
codes on: https://ascii.cl/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With