Spring rest: Consuming x-www-form-urlencoded associative array - spring

I am trying to PUT an associative array:
name[en_US]:Administrator
name[es_ES]:Administrador
name[no_NO]:Administrator
How do I configure the rest controller method to consume this data?
I have tried the following without any luck:
#RequestMapping(value = "/{userGroupId}", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.OK)
public void updateUserGroup( #PathVariable Long userGroupId,
#RequestParam(value = "name", required = false) Map<String, String> name)
The data not passed as JSON, but as x-www-form-urlencoded.
EDIT 1:
If I leave out "(value = "name", required = false) from the #RequestParam I can get all request parameters as key value pairs, but isn't there a way to bind it to a Map? If not I would have to do some string manipulation to create that map manually.

Related

How to use #RequestParam Map<String,String> properly in Swagger UI?

I'm trying to use springfox-swagger-ui for this request:
#GetMapping(value = "")
public String Hello( #RequestParam Map<String, String> params )
When I open Swagger UI and try the request, it shows the parameters like this:
and the request query string will be like:
?params%5BadditionalProp1%5D=string&params%5BadditionalProp2%5D=string&params%5BadditionalProp3%5D=string
I don't want the word "params" to be included in the query string, I want the parameters be like ?additionalProp1=string ....
How can I achieve this?
Add the following #Parameter annotation to your parameter (line breaks added for readability). The style and explode attributes specify that the map parameter should be serialized as ?key1=value1&key2=value2&... without including the parameter name ("params").
#GetMapping(value = "")
public String Hello(
#Parameter(name = "params",
in = ParameterIn.QUERY,
required = true,
schema = #Schema(type = "object", additionalProperties = true),
style = ParameterStyle.FORM,
explode = Explode.TRUE)
#RequestParam Map<String, String> params
)

How do I get the names of the request parameters for a Spring REST URL?

I have a Spring REST API and I don't know what the parameter names will be ahead of time. It's like this ...
/myapp/api/employees?firstname=Bob&lastname=Jones
Which basically becomes ... SELECT * FROM employees WHERE firstname = 'bob' and lastname = 'jones';
/myapp/api/customers?customerNumber=12345
Basically becomes ... SELECT * FROM customers WHERE customerNumber = '12345';
If I knew the params before hand (like 'firstname') then I could do this ...
#RequestMapping(value = "/{entityType}", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> getEntity(#PathVariable String entityType, #RequestParam(required = false) String firstname) throws Exception {
... but I don't know the names of the parameters before hand. They can be anything.
How do I get the list of parameter names that were passed in?
Answering my own question. Found the solution in this article here ...
#RequestMapping(value = "/{entityType}", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> getEntity(#PathVariable String entityType, #RequestParam Map<String,String> allParams) throws Exception {
allParams is now a key-value map of all params and values passed it.

Why can #requestparam get file upload data in SpringMVC?

#requestparam functions like request.getquerystring (). Why does she receive a multipart/form-data type contentType when #requestbody cannot?Please tell me why?
#PostMapping(value = "/uploadFileByUserTrainId", consumes = "multipart/form-data")
#Student({Student.Authority.A, Student.Authority.B, Student.Authority.C})
public WebMessage uploadFileByUserTrainId(
#RequestParam(value = "document", required = false) MultipartFile multipartFile,
#RequestParam(value = "documetnRe", required = false) MultipartFile multipartFileRe,
#RequestParam("id") long id,
#RequestParam(value = "documentFileType", required = false) String fileType,
#RequestParam(value = "documentFileReType", required = false) String fileReType,
HttpServletRequest httpServletRequest) {
// todo
}
It is nothing wrong using #RequestParam with Multipart file.
#RequestParam annotation can also be used to associate the part of a "multipart/form-data" request with a method argument supporting the same method argument types. The main difference is that when the method argument is not a String, #RequestParam relies on type conversion via a registered Converter or PropertyEditor

How can I validate the value of #RequestQuery

I am trying to validate the value of the query param below after the equals sign in the REST URI, does anyone know how to do it with Spring 4.1 please?
I want to validate in the method parameters that 'drive' is the passed param but all I can validate is the operation part
I would like to do something like #RequestParam(value = "drive")
localhost/test?operation=drive
#RequestMapping(value = "/test", method = RequestMethod.PUT)
public ResponseEntity<Void> operation(#RequestParam(value = "operation", required = true) String operation)
`
You could use Bean Validation annotations.
If you want to check if the value is allowed, you can use #Pattern with a regular expression:
#Pattern(regexp = "value1|value2|value3", flags = Pattern.Flag.CASE_INSENSITIVE)
#RequestMapping(value = "/test", method = RequestMethod.PUT)
public ResponseEntity<Void> operation(
#RequestParam(value = "operation", required = true)
#Pattern(regexp = "value1|value2|value3", flags = Pattern.Flag.CASE_INSENSITIVE)
String operation) {
...
}

Spring MVC forward appending request parameter values comma separated when we have same parameter name for topRequest and forward request

Spring MVC forward appending request parameter values comma separated when we have same parameter name for topRequest and forward request
#RequestMapping(path = "/details")
public ModelAndView details(#ModelAttribute final DetailsForm detailsForm){
//DetailsForm contain a parameter called destinationId with value 1234
final ModelAndView mav = new ModelAndView();
//Some logic to get targeted destinationId (7890) using destinationId (1234) from detailForm
mav.setViewName("forward:/search?destinationId=7890");
return mav;
}
#RequestMapping(path = "/search")
public ModelAndView details(#ModelAttribute final SearchForm searchForm){
//Here I tried to get destinationId from model-attribute searchForm
final Integer destinationId = searchForm.getDestinationId();
//Then it returned me 1234,7890
}
Can someone please help me out how to resolve this. I want to get only 7890.
I am interested in the answer also. I also hit this problem hacked it by adding a method:
private String getLastPartFromFormValue(final String value) {
if (value == null)
return null;
String[] parts = value.split(",");
return parts[parts.length -1];
}
Just for sake of knowledge.
If you have a method, and you have a query param named thing and have an object annotated with #ModelAttribute and, in that object you have a field with the same name of your query param, you can expect that behavior.
For example:
#PostMapping(value = "/my-awesome-path")
public String myAwesomeMethod(
#RequestParam(name = "token", required = false) final String token,
#ModelAttribute("formData") final MyFormData formData) {
//class fields and members...
And, in the MyFormData you have this:
public class MyFormData{
private String token;
//other fields, getters and setters...
You will receive the query param token with the value duplicated and comma separated as well as in the MyFormData object.
The alternative is check the casuistic and change the parameter name or redesign if it's necessary.
In the example the query param name is changed like this:
#PostMapping(value = "/my-awesome-path")
public String myAwesomeMethod(
#RequestParam(name = "custom-token", required = false) final String customToken,
#ModelAttribute("formData") final MyFormData formData) {
//class fields and members...
And the values are not more duplicated nor comma separated.
Cheers.

Resources