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

#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)

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

#RequestHeader mapped value contains header twice

We are facing a super strange problem: in our endpoint:
#PostMapping(value = "/send_event_to_payment_process")
#Async
public void sendEvent(#Valid #RequestBody final SendEventRequestDto dto, #RequestHeader(value = TENANT) String foo) {
the mapped #RequestHeader variable foo contains the vaue twice joined with a ',' ("test,test"). If we read the header programmatically using the request context:
public void sendEvent(#Valid #RequestBody final SendEventRequestDto dto, #Context final HttpServletRequest request) {
final String tenant = request.getHeader(TENANT);
we receive the proper value (only once: "test").
Any clues what the problem might be?!
Thank you!
You are comparing different things.
The HttpServletRequest.getHeader method always returns a single value, even if there are multiple values for the header. It will return the first (see the javadoc of the method).
Spring uses the HttpServletRequest::getHeaders method to get all the values. Which retrieves all header values and, depending on the value, return the String[] or creates a single concatenated String.
To compare the same things you also should use the getHeaders method and then you will have the same result. Which means your request contains 2 header values for the given header.

HttpServletRequest in spring getting parameters values as null for post request

#ResponseBody
#RequestMapping(value = {"apiRequest"}, method = {RequestMethod.POST})
public String contestApiSignUp(HttpServletRequest req) throws JSONException {
try {
String username = req.getParameter("username");
String firstname = req.getParameter("firstname");
String lastname = req.getParameter("lastname");
String password = req.getParameter("password");
String phone = req.getParameter("phone");
Here the values I am getting all are null. That is username =null, firstname =null...
I am hitting post request with the values
http://localhost:8080/apiRequest.htm
username = Subhajit
firstname = Subha
...
like this.
But while I am using same code but,
#RequestMapping(value = {"apiRequest"}, method = {RequestMethod.GET})
using GET instead of POST then I am getting the proper values.
When you sent your HTML Form by POST to your URL /apiRequest, did you fill your data (username, firstname etc.) in fields in your form, or did you attached them to the sent URL (eg. apiRequest.htm?username=test&...) ?
Because with the second approach, you data will be accessible only through a GET request, not a POST. The first approach will work with a POST request.
Also, you do not need to call explicitly getParameter on the HttpServletRequest in a Spring Controller.
You can do this :
#ResponseBody
#RequestMapping (value = "apiRequest", method = RequestMethod.POST)
public String contestApiSignUp(
#RequestParam ("username") String username,
#RequestParam ("firstname") String firstname,
#RequestParam ("lastname") String lastname,
#RequestParam ("password") String password,
#RequestParam ("phone") String phone) {
return "Hello World";
}
From the comments, you said you are trying with postman to post the request, So are you building website or webservices? either way you should not be sending your data in the headers.
If you are building a website put together an HTML file from which
you can submit a form to this controller
If you are building webservice, change the controller and let it
accept JSON (or XML -I would discourage this though) body. Follow
this https://stackoverflow.com/a/40226580/6785908. And then from
postman (or curl), post a json instead.

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,

Spring request mapping with Paypal

For the return URL, it seem you have to define the whole URL like so:
String returnURL = "http://localhost:8080/appName/shopping/confirmorder";
Now, I have a problem with the request mapping:
#RequestMapping(value = "/shopping/confirmorder?token={token}&PayerID={payerID}", method = RequestMethod.GET)
public String doGet(#PathVariable("token") String token, #PathVariable("payerID") String payerID,
HttpServletRequest request) {
// do stuff
}
The controller is never called for some reason?
The final returnURL returned from Paypal is like this:
http://localhost:8080/appName/shopping/confirmorder?token=EC-4...G&PayerID=A...W
Note the Ids have been edited.
If you have two path variables named token and payerID, then the method signature should be
public void doGet(#PathVariable("token") String token,
#PathVariable("payerID") String token,
HttpServletRequest request,
HttpServletResponse response)
How did you expect Spring to put those two strings inside a single option parameter of type int?
See http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates
Moreover, PathVariable is used to bind portions of the request path to method arguments. In your case, you have request parameters. You should thus use #RequestParam:
#RequestMapping(value = "/shopping/confirmorder", method = RequestMethod.GET)
public void doGet(#RequestParam("token") String token,
#RequestParam("PayerID") String token,
HttpServletRequest request,
HttpServletResponse response)
See http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestparam

Resources