Binding a list in @RequestParam
Arrays in @RequestParam
are used for binding several parameters of the same name:
myparam=myValue1&myparam=myValue2&myparam=myValue3
If you need to bind @ModelAttribute
-style indexed parameters, I guess you need @ModelAttribute
anyway.
Is it impossible to have a @RequestParam as a List?
The most common & standard way to pass a list of values as URL parameters is to repeat them i.e.
http://rentacar.com/api/v1/search?make=audi&model=A8&type=6&type=11&type=12&color=RED&color=GREY
Now the question is to handle such input in Spring MVC REST endpoint? Lets assume you are developing a search api to find cars available to rent; this is how you will do it:
public List<Vehicle> search(@RequestParam(value="make", required=false) String make, @RequestParam(value="model", required=false) String model, @RequestParam(value="type", required=false) List<String> types, @RequestParam(value="color", required=false) List<String> colors) {
....
}
https://medium.com/@rasheedamir/spring-mvc-how-to-pass-list-of-values-as-url-parameters-5d57dcac8457
Spring - Binding list with request param
So, i find a solution to fix my issue :
In my query, I set my query to : {"status":"ACTIVE,INACTIVE"}
instead of {"status":["ACTIVE","INACTIVE"]}
Binding a list in @RequestParam includes square brackets
You don't need to use []
syntax to pass arrays (or lists).
Try to execute your request this way:
/countRequests?languages=EN,IT
This way Spring MVC should bind your parameter correctly. Take a try.
Another way is to use this syntax:
/countRequests?languages[]=EN&languages[]=IT
In Spring, how do I bind a list of integers to a RequestParam?
The problem you are facing is that java has type erasure. So at runtime a List<Integer>
is equivalent than a List<String>
and spring has no way of knowing you want Integers into your list.
A work around might be using a integer array instead of a List of integers.
@RequestMapping("/delete.x")
public @ResponseBody Map<String, Object> delete(HttpServletRequest request,
@RequestParam("ids[]") Integer[] ids) {
Spring MVC @RequestParam a list of objects
Request parameters are a Multimap of String to String. You cannot pass a complex object as request param.
But if you just pass the username that should work - see how to capture multiple parameters using @RequestParam using spring mvc?
@RequestParam("users") List<String> list
But I think it would be better to just use the request body to pass information.
Spring MVC: Issues Binding Request Parameters to a Generic List
You can implement your own HandlerMethodArgumentResolver like this:
@Component
public class HolderMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return Holder.class.isAssignableFrom(methodParameter.getParameterType());
}
@Override
public Holder resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
Class<?> genericClass = (Class<?>) ((ParameterizedType) methodParameter.getGenericParameterType()).getActualTypeArguments()[0];
if (Integer.class.isAssignableFrom(genericClass)) {
String[] values = nativeWebRequest.getParameterValues("items");
List<Integer> convertedValues = Stream.of(values).map(Integer::valueOf).collect(Collectors.toList());
return new Holder<>(convertedValues);
}
if (String.class.isAssignableFrom(genericClass)) {
String[] values = nativeWebRequest.getParameterValues("items");
return new Holder<>(Arrays.asList(values));
}
throw new IllegalArgumentException("Generic type " + genericClass + " doesn't support");
}
}
And after that you can define in contoller different methods:
@GetMapping("/test")
public String test(Holder<Integer> holder) {
List<Integer> items = holder.getItems();
System.out.println(items.size());
System.out.println(items);
if (!items.isEmpty()) {
System.out.println(items.get(0).getClass());
}
return "test";
}
@GetMapping("/test2")
public String test2(Holder<String> holder) {
List<String> items = holder.getItems();
System.out.println(items.size());
System.out.println(items);
if (!items.isEmpty()) {
System.out.println(items.get(0).getClass());
}
return "test2";
}
How/Why does parameter binding work without @RequestParam?
Who is in charge of solving if you do not place any annotation on parameters?
It is this RequestParamMethodArgumentResolver the documentation says:
Resolves method arguments annotated with @RequestParam, arguments of
type MultipartFile in conjunction with Spring's MultipartResolver
abstraction, and arguments of type javax.servlet.http.Part in
conjunction with Servlet 3.0 multipart requests. This resolver can
also be created in default resolution mode in which simple types (int,
long, etc.) not annotated with @RequestParam are also treated as
request parameters with the parameter name derived from the argument
name. If the method parameter type is Map, the name specified in the
annotation is used to resolve the request parameter String value. The
value is then converted to a Map via type conversion assuming a
suitable Converter or PropertyEditor has been registered. Or if a
request parameter name is not specified the
RequestParamMapMethodArgumentResolver is used instead to provide
access to all request parameters in the form of a map.A WebDataBinder is invoked to apply type conversion to resolved
request header values that don't yet match the method parameter type.
So that is the reason why it works.
RequestParam with map is unnecessarily binding other request params in GET request
As mentioned in the comments, you can't exclude params for the @RequestParam
map.
Do your client have the option to send those params with the body as a json object instead of as request parameters? A request body isn't normally sent in GET Requests, but you could do it. Then you would change @RequestParam<String, String> map)
to @RequestBody Map<String, String> map)
Related Topics
Ways to Save Enums in Database
Eclipse - Java.Lang.Classnotfoundexception
How to Log Spring 5 Webclient Call
How Is Driver Class Located in Jdbc4
Hibernate: "Field 'Id' Doesn't Have a Default Value"
Parsing PDF Files (Especially with Tables) with PDFbox
How to Insert an Pdpage Within Another Pdpage with PDFbox
How to Dynamically Build a Multi-Dimensional Array in Java
Tablecellrenderer and How to Refresh Cell Background Without Using Jtable.Repaint()
Splitting a CSV File with Quotes as Text-Delimiter Using String.Split()
Getting Active Window Information in Java
What Does Inputstream.Available() Do in Java
How to Build a Docker Container for a Java Application