None required PathVariable not working - spring

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)

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.

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