Spring Boot Controller map request params, path variables and body to a custom object - spring-boot

I have a pretty convoluted method in my controller, with various request params, headers and path variables:
public CompletableFuture<ResponseEntity<?>> retrieveAndCache(
#PathVariable(name = "collection") String collection,
#PathVariable(name = "handler") String handler,
#RequestBody(required = false) JsonNode reqBody,
#RequestHeader(name = "X-Server", required = false) String _server,
#RequestHeader(name = "X-Host", required = false) String host,
#RequestHeader(name = "X-ClearCache", required = false, defaultValue = "false") Boolean clearCache,
#RequestHeader(name = "X-ReturnImmediately", required = false, defaultValue = "false") Boolean returnImmediately,
#RequestHeader(name = "X-JustEcho", required = false, defaultValue = "false") Boolean justEcho,
#RequestParam Map<String, String> requestParams,
#RequestParam(name = "excludedServers", required = false) String... excludedServers)
Looking at it makes me dizzy.
Is it possible to map all of this to a custom object like:
public CompletableFuture<ResponseEntity<?>> retrieveAndCache(Parameters p)...
I know we can use custom converters in spring, but afaik they work to convert a single header or single variable to an object. This way I thought it may be more readable, plus maybe I can move some methods (validation etc.) into Parameters class.

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
)

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 REST - At least one RequestParameter mandatory

I have a method with below RequestMappings:
#RequestParam(value = "someValue1", required = false) final String someValue1
#RequestParam(value = "someValue2", required = false) final String someValue2
Both the parameters are marked as optional. And currently I check which attribute is provided and based on that some action is taken. Is it possible to enforce at least one of the two parameters should always be present in the request?
PS: I am not looking at creating two different end points.
Just send the request parameter as a String map and mark that as mandatory attribute.
public #ResponseBody String your_method(
#RequestParam(value = "parameterMap",
required = true) Map<String,String> params){
//String someValue1 = params.get("someValue1");
// String someValue2 = params.get("someValue2");
}
Here you have to pass either or both of the parameters.

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

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.

Resources