How to have multiple parameters using Spring MVC RequestMapping? - java

I am using Spring MVC RequestMapping here for GET parameters. Below is my code -
#RequestMapping(value = "index", method = RequestMethod.GET)
public HashMap<String, String> handleRequest(#RequestParam("dc1Servers") String dc1Servers) {
HashMap<String, String> model = new HashMap<String, String>();
String helloWorld = "Hello World!";
model.put("greeting", helloWorld);
System.out.println(dc1Servers);
return model;
}
I am hitting this URL - http://127.0.0.1:8080/dataweb/index?dc1Servers=7 then it goes into the above code and prints out 7 on the console and works fine.
Now I would like to have these two below parameters as well -
dc2Servers=7
dc3Servers=7
So I made a method like this which can take three input parameters -
#RequestMapping(value = "index", method = RequestMethod.GET)
public HashMap<String, String> handleRequest(#RequestParam("dc1Servers") String dc1Servers, #RequestParam("dc2Servers") String dc2Servers, #RequestParam("dc3Servers") String dc3Servers) {
HashMap<String, String> model = new HashMap<String, String>();
String helloWorld = "Hello World!";
model.put("greeting", helloWorld);
System.out.println(dc1Servers);
System.out.println(dc2Servers);
System.out.println(dc3Servers);
return model;
}
Now if I hit the url like this then it doesn't works -
http://127.0.0.1:8080/dataweb/index?dc1Servers=7?dc2Servers=7?dc3Servers=7
And it gives me some error.. Any idea what wrong I am doing here?

This should be
http://127.0.0.1:8080/dataweb/index?dc1Servers=7&dc2Servers=7&dc3Servers=7
change an try again
& works between each parameter
? only works at the begin of the url parameters
Check this example
http://www.example.com/products/women/dresses?sessionid=34567&source=google.com

Related

What's the best way to encode and decode parameter in springboot?

I use #RequestParam to get the parameter value,but I find the if I pass the value like 'name=abc&def&id=123',I will get the name value 'abc' instead of 'abc&def'. I find the encode and decode the parameter value can solve my problem.But I have to write the encode and decode mehtod in every controller method,Do spring have the global mehtod that decode every #RequestParam value?When using #RequestParam, is it necessary to encode and decode every value?
Here is my code:
#PostMapping("/getStudent")
public Student getStudent(
#RequestParam String name,
#RequestParam String id) {
name= URLDecoder.decode(name, "UTF-8");
//searchStudent
return Student;
}
#PostMapping("/getTeacher")
public teacher getTeacher(
#RequestParam String name,
#RequestParam String teacherNo) {
name= URLDecoder.decode(name, "UTF-8");
//searchTeacher
return teacher;
}
Somebody say the the Spring will have already done this,but I have try,the result is not right.Only use curl cmd is ok,but java code is not ok.
#PostMapping(value = "/example")
public String handleUrlDecode1(#RequestParam String param) {
//print ello%26test
System.out.println("/example?param received: " + param);
return "success";
}
#GetMapping(value = "/request")
public String request() {
String url = "http://127.0.0.1:8080/example?param=ello%26test";
System.out.println(url);
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject(url, null, String.class);
}
You must create an HTTP entity and send the headers and parameter in body.
#GetMapping(value = "/request")
public String request() {
String url = "http://127.0.0.1:8080/example";
System.out.println(url);
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("param","ello&test");
map.add("id","ab&c=def");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
return restTemplate.postForObject(url, request, String.class);
}
As you can read here, the escape character for & is %26.
So you should use the following
name=abc%26def&id=123
If you don't use an escape character according to URL standards, Spring will try to use what follows & and try to match it as a new query parameter.
No need to manually use URLDecoder, SpringBoot controllers will handle it for you.
#RestController
public class UrlDecodeController {
#GetMapping(value = "/example")
public String handleUrlDecode(#RequestParam String param) {
System.out.println("/example?param received: " + param);
return "success";
}
#PostMapping(value = "/example2")
public String handleUrlDecodeInPostRequest(#RequestParam String param1, ExamplePayload payload) {
System.out.println("/example2?param1 received: " + param1);
System.out.println("request body - value1: " + payload.getValue1());
return "success";
}
#GetMapping(value = "/request")
public String request() {
String url = "http://localhost:8080/example2?param1=test1&test2";
System.out.println(url);
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("value1","test1&test2");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
return restTemplate.postForObject(url, request, String.class);
}
class ExamplePayload{
private String value1;
private String value2;
//getters and setters
public ExamplePayload() {
}
}
}
Call with GET /example?param=hello%26test and the System.out.println outputs:
/example?param received: hello&test
Call the POST using curl as an example:
curl -X POST "http://localhost:8080/example2?param1=test1%26test2" -d "value1=test3%26test4"
Prints:
/example2?param1 received: test1&test2
request body - value1: test3&test4
Added GET /request to show using RestTemplate with the application/x-www-form-urlencoded Content-Type. Note that RestTemplate will automatically url encode any values passed as request parameters or in the request body. If you pass a String value of "%26" it will pass it as is, this is what you are seeing in your example. If you pass "&" it will url encode it to "%26" for you, and the Controller decodes it automatically on the other side.

how to Populate fields from URL parameter in java Springboot

I need to add support for passing field values to a form via a URL parameter when viewing a form which will be used to populate values into the form when it loads. should support a JSON formatted value of field names and values. Example:
https://web/form/view?id=1&data={'fieldname':'value'}
#RequestMapping(value = "/form/view", method = RequestMethod.GET)
public ModelAndView viewDomainForm(HttpSession session, #ModelAttribute("command") FormBean inFormBean) {
Form form = formService.getForm(inFormBean.getId());
FormInstance formInstance = formInstanceService.createFormInstance(form);
String formInstanceId = (String) session.getAttribute("formInstanceId");
if (formInstanceId != null && formInstanceId.length() > 0) {
formInstanceService.deleteFormInstanceById(formInstanceId);
}
formInstanceId = formInstance.getId();
session.setAttribute("formInstanceId", formInstanceId);
FormBean formBean = prepareFormBean(form);
formBean.setEmbed(inFormBean.isEmbed());
formBean.setFormInstanceId(formInstance.getId());
Map<String, Object> model = new HashMap<String, Object>();
model.put("externalBaseUrl", configurationService.getValue("core.external.url.base"));
model.put("fromTaskList", false);
model.put("form", formBean);
model.put("flow", new FlowBean());
model.put("task", new TaskBean());
return new ModelAndView("form-viewer", model);
}
I have this method for viewing. what would be the best way to Populate fields from URL parameter?
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
// this is the value that will populate into the form when it loads.
First question, why not use POST with the JSON in the request body?
If the JSON will be large, then you will run in a URL limitation problem. And you have to encode your URL with % and different delimiters which will make it even less debuggable.
But it is doable.
Let's say that you correctly encoded your URL and the JSON is as a query param.
What you could do is receive it and either traverse it and create/populate your form or map it to an object and use that:
public ModelAndView viewDomainForm(... #RequestParam("data") String jsonDataInUrl...)
{
// Work with jsonDataInUrl either through parsing it or through transforming it into a java bean.
...
}
Here is a URL decoder/encoder in case you need it.

Bad request with RestTemplate -> postForObject (Spring Boot)

I'm experiencing some troubles with a simple matter.
I'm trying to send a request to other REST service
//getting restTemplate from RestTemplateBuilder.build()
//endpoint and rest of variables came in properties
Map<String, String> map = new HashMap<>();
map.put("app", app);
map.put("username", username);
map.put("password", password);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
String token = restTemplate.postForObject(loginEndpoint, headers, String.class, map);
And I recive:
Unexpected error occurred in scheduled task.
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
The weird thing, when I use a simple CURL call and works smooth.
Already checked the variables and endpoint, and it's correct.
In this case, endpoint must have appropiate placeholders on end point url.
I made this method to do it easy:
private String placeHolders(Map<String, String> values){
String response = "?";
boolean first = true;
for(Map.Entry<String, String> entry:values.entrySet()){
if(first){
first = false;
}else{
response+="&";
}
response+=entry.getKey()+"="+entry.getValue();
}
return response;
}
And the call now Is:
String token = restTemplate.postForObject(loginEndpoint+placeHolders, headers, String.class, map);

How to resolve URI parameters in string URL through java/spring code?

I have url like http://www.example.com/api/{uriparam}/something
How should I replace the uriparam with my parameter call test?
So that it will be like http://www.example.com/api/test/something
In rest API its called as path, to do that, here is sample of controller using path. here is sample with jax rs.
#Path("/testUrl/{data}")
#GET
public String checkPending(#PathParam("data") String data) {
String yourUrl = "http://www.example.com/api/" + data + "/something";
return yourUrl;
}
You can use org.springframework.web.util.UriComponentsBuilder as below :-
Map<String, String> parameters = new java.util.HashMap<String,String>();
parameters.put("uriparam","test");
String url = UriComponentsBuilder.fromHttpUrl("http://www.example.com/api/{uriparam}/something".trim()).buildAndExpand(parameters).encode().toString();
it will return you the required url

How to use Spring`s RestTemplate to POST an array of strings

I am trying to post a simple array of strings using the spring`s restTemplate. Did anyone succeed with that ?
The client:
public void save(){
String company = "12345";
String productId = "10";
String[] colors = {"A","B","C","D","E"};
String convertUrl = "http://localhost:8080/cool-web/save";
MultiValueMap<String, Object> convertVars = new LinkedMultiValueMap<String, Object>();
convertVars.add("companyID", StringUtils.trimToEmpty(company));
convertVars.add("productId", StringUtils.trimToEmpty(productId));
convertVars.add("disclaimer", StringUtils.trimToEmpty("ffs"));
convertVars.add("colorsArray", colors);
restTemplate.postForObject(convertUrl, null, String.class, convertVars);
}
The Service is:
#RequestMapping(value = "/save", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.OK)
public void save(#RequestParam("colorsArray[]") String[] colors,
#RequestParam("disclaimer") String disclaimer,
#RequestParam("companyID") String companyID,
#RequestParam("productId") String productId) {
resourceService.save(colors, disclaimer, companyID, productId);
}
I got 400 Bad Request.
What am I doing wrong ?
I am using the default messageConverters.
Do I need to implement custom messageConverter for a simple array of Strings ?
Here is the solution:
public void save(){
String company = "12345";
String productId = "10";
String[] colors = {"A","B","C","D","E"};
String convertUrl = "http://localhost:8080/cool-web/save";
MultiValueMap<String, Object> convertVars = new LinkedMultiValueMap<String, Object>();
convertVars.add("companyID", StringUtils.trimToEmpty(company));
convertVars.add("productId", StringUtils.trimToEmpty(productId));
convertVars.add("disclaimer", StringUtils.trimToEmpty("ffs"));
for(String color:colors){
convertVars.add("colorsArray[]", color);
}
restTemplate.postForObject(convertUrl, convertVars , String.class);
}
If you are trying POST MultiValueMap, use Map.class instead of String.class in the code:
restTemplate.postForObject(convertUrl, null, Map.class, convertVars);
And your service method is wrong I guess. Because you are posting MultiValueMap and in save method you are trying to get all the internal variables as method parameters i.e. RequestParam.
That's not going to happen. You will have to accept only MultiValueMap there and take things out of it for use.
public void save(#RequestParam("colorsArray[]") MultiValueMap<String, Object> convertVars ) {
resourceService.save(convertVars.getColors(), .... );
}
#RequestParam(value) value - "The name of the request parameter to bind to." So #RequestParam("colorsArray[]") String[] colors trying to find param with name "colorsArray[]" but u put parameter with name "colorsArray". May be that is the reason.

Categories

Resources