How can I validate the value of #RequestQuery - spring

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) {
...
}

Related

Spring boot : REST API behaviour inconsistent post version upgrade

I have issue after upgrading to Spring Boot 2.3.0.RELEASE from 1.5.10.RELEASE. Our controller API looks like -
#RequestMapping(value = "/card", method = RequestMethod.GET)
public CardRespDTO getCards(#RequestParam String profileId, #RequestParam(required = false) String banner, #RequestParam(required = false) String paymentGatewayVersion);
Consumer were able to call this API by not passing profileId param but by just providing some USER_ID header. But post the version upgrade, those calls are failing with below error -
org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'profileId' is not present
Can someone please help identifying the issue here? We can't ask consumer to make a change.
Marking profileId as not required should do the trick:
#RequestMapping(value = "/card", method = RequestMethod.GET)
public CardRespDTO getCards(#RequestParam(required = false) String profileId,
#RequestParam(required = false) String banner,
#RequestParam(required = false) String paymentGatewayVersion)

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.

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

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.

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

None required PathVariable not working

I got the following code:
#GetMapping(value = "/user/{username}/{auth_key}", produces = MediaType.APPLICATION_JSON_VALUE)
public ProfileRequest getUser(final #PathVariable("username") String username,
final #PathVariable(value = "auth_key", required = false) UUID authKey) {
and I can't understand why /user/{username} does not handle my request.
Mfg.
/user/{username}/{auth_key} and /user/{username} are different URLs. Putting all these URLs to #GetMapping annotation will resolve your problem:
#GetMapping(value = {"/user/{username}/{auth_key}", "/user/{username}/"}, produces = MediaType.APPLICATION_JSON_VALUE)

Resources