Required request parameter for method parameter type String[] is not present spring boot - spring

I am trying to read an array value from query param which is passes as
ot-replace[0]=kin43
On the controller I have
#GetMapping(value = "/{userId}/**")
public ResponseEntity<String> viewObject(#PathVariable(value = "userId") String uid,
#RequestParam(name="ot-replace")String[] regexReplace){}
I get the following error
"trace": "org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'ot-replace' for method parameter type String[] is not present\r\n\tat org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValueInternal(RequestParamMethodArgumentResolver.java:218)\r\n\tat org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:193)\r\n\tat org.springframework.web.

instead of ot-replace[0]=kin43 replace with ot-replace=kin43&ot-replace=kin44
You will get two item in your array.

Related

Issue with Spring Rest #RequestMapping when negating params

I have two spring controller methods :
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = "!applicationId") //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = {"idNumber","applicationId"}) //existing customer
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
}
using "!applicationId" , I am expecting that when I call the url with applicationId parameter there that the second method will be called , but actually when I pass a request like this :
{"idNumber":"345","applicationId":"64536"}
The first method gets called
This is the part of the params paremeters documentation that I rely on :
Finally, "!myParam" style expressions indicate that the specified
parameter is not supposed to be present in the request.
Can't you just simply delete first request params?
#RequestMapping(value="/requestotp",method = RequestMethod.POST) //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
The issue actually wasn't with negating the parameter, the issue was that I was sending {"idNumber":"345","applicationId":"64536"} in the POST body and I was expecting the variables to be mapped to the method parameters annotated with #RequestParam ... this is not correct ... #RequestParam only map URL parameters .... so the controller was trying to find the best match so it was using the first method as it contained #RequestBody

#RequestParam value converted to lower case

I've a simple controller containing a request param like:
#RequestParam(required = false) String name
Now I also have mockmvc test containing:
mockMvc.perform(get("/rest/hello/greet")
.param("name", "Marcel"))
In the logging I see it seems the request param is passed through correctly:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /rest/hello/greet
Parameters = {name=[Marcel]}
However in my controller the request param comes in in lowercase..
#Get(path = "/greet", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<JSONObject> greet(#RequestParam(required = false) String name) {
logger.info("greet called with name: {}", name);
It prints greet called with name: marcel.
Also - obviously - when passing this argument to other service it is passed as lowercase.
It's a very simple Spring Boot application so I wonder why this request param is coming in in lowercase.
Found the issue some Converter<String, String> was in application context which was causing this issue.

How to pass String array in #RequestParam in REST GET API call through POSTMAN or DHC REST application?

I have following REST controller in Java Spring Application:
#RequestMapping(
value = "/api/getApplication/{me_userId}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public Object getApplication(
#PathVariable String userId,
#RequestParam(value="fieldNames[]", required = false) String[] fieldNames) {
if (fieldNames != null) {
for (String fieldName : fieldNames)
System.out.println(fieldName);
}
...
return null;
}
So I can not succeed in simulating API call from DHC REST of POSTMAN what will pass that fieldNames[].
Does anyone know how to do it?
First of all, your current method does not work because your #PathVariable is wrong. In your #RequestMapping you have the following placeholder in your path: {me_userId}, which means that it will be mapped to a path variable with that name.
However, the only #PathVariable you have is nameless, which means it will use the name of the parameter (userId) in stead.
So before you try to execute your request, you have to change your #RequestMapping into:
#RequestMapping(
value = "/api/getApplication/{userId}", // <-- it's now {userId}
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
Then, if you run the application, you can kinda choose how you want to pass your parameters. Both the following will work:
?fieldNames[]=test,test2
Or:
?fieldNames[]=test&fieldNames[]=test2
Both these results should print the desired results.

how to capture multiple parameters using #RequestParam using spring mvc?

Suppose a hyperlink is clicked and an url is fired with the following parameter list myparam=myValue1&myparam=myValue2&myparam=myValue3 . Now how can I capture all the parameters using #RequestParam in spring mvc?
My requirement is I have to capture all the params and put them in a map.
Please help!
#RequestMapping(value = "users/newuser", method = RequestMethod.POST)
public String saveUser(#RequestParam Map<String,String> requestParams) throws Exception{
String userName=requestParams.get("email");
String password=requestParams.get("password");
//perform DB operations
return "profile";
}
You could use RequestParam in the above mentioned manner.
It seems you can't get
Map<String,String>
because all your params have same name "myparam"
Try this instead:
public ModelAndView method(#RequestParam("myparam") List<String> params) { }
To get all parameters at once try this:
public ModelAndView postResultPage(#RequestParam MultiValueMap<String, String> params)
This feature is described in the #RequestParam java doc (3. Paragraph):
Annotation which indicates that a method parameter should be bound to a web request parameter. Supported for annotated handler methods in Servlet and Portlet environments.
If the method parameter type is Map and a request parameter name is specified, then the request parameter value is converted to a Map assuming an appropriate conversion strategy is available.
If the method parameter is Map<String, String> or MultiValueMap<String, String> and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.
As of Spring 3.0, you can also use MultiValueMap to achieve this:
A rudimentary example would be:
public String someMethod(#RequestParam MultiValueMap<String,String> params) {
final Iterator<Entry<String, List<String>>> it = params.entrySet().iterator();
while(it.hasNext()) {
final String k = it.next().getKey();
final List<String> values = it.next().getValue();
}
return "dummy_response";
}
If anyone is trying to do the same in Spring Boot, use RequestBody in place of RequestParam
Spring mvc can support List<Object>, Set<Object> and Map<Object> param, but without #RequestParam.
Take List<Object> as example, if your object is User.java, and it like this:
public class User {
private String name;
private int age;
// getter and setter
}
And you want pass a param of List<User>, you can use url like this
http://127.0.0.1:8080/list?users[0].name=Alice&users[0].age=26&users[1].name=Bob&users[1].age=16
Remember to encode the url, the url after encoded is like this:
http://127.0.0.1:8080/list?users%5B0%5D.name=Alice&users%5B0%5D.age=26&users%5B1%5D.name=Bob&users%5B1%5D.age=16
Example of List<Object>, Set<Object> and Map<Object> is displayed in my github.
You can use for multiple Params as such
public String saveUser(#RequestParam("email") String userName, #RequestParam("password") String password) throws Exception{
//your code
//perform DB operations
return "profile";
}
For params with same name, you can use MultiValueMap<String ,String>. Then all the values would be present as List
You can use multiple #RequestParam annotations as shown below.
#RequestParam(value="myparam1", required = true) <Datatype> myparam1,
#RequestParam(value = "myparam2", required = false) <Datatype> myparam2,

Need to set parameter value and datatypes taken from URI of resful web service into HashMap

#RequestMapping(value = "/{methodName}/{responseType}", method = RequestMethod.GET)
public ModelAndView execute(#PathVariable String methodName, #PathVariable String responseType,
HttpServletRequest request, HttpServletRequest response){
Map<String,String> yesMap = new HashMap<String,String>();
}
As shown in code above I need to get data types of parameters passed from {responseType} and set the same in yesMap against parameter values.
String param=request.getParameter("id");
is returning null values.
need to get data types of parameters passed from {responseType}
Its type will always be String as you are collecting it in responseType which is String.
get data types of parameters passed from {responseType} and set the same in yesMap against parameter values
I think yesMap.put("String",responseType); will do.
In the code you posted above, the follwign call
yourRootUrl/cheese/stilton
will result in these being true in your "execute" method:
methodName.equals("cheese");
responseType.equals("stilton");
I don't understand what you are trying to achieve. Your parameter names are confusing.
Its quite simple, you have declared two string paramters, which thanks to spring can be path variables.
This is a GET request, so getParamter won't work, try using String param=request.getAttribute("id"); which is completely unrelated to your path variables. Or the differetn annaotion RequestParam like so :
#RequestMapping(value = "/{methodName}/{responseType}", method = RequestMethod.GET)
public ModelAndView execute(#PathVariable String methodName, #PathVariable String responseType, #RequestParam int id)

Resources