Multipartfile parameter order precedence causing error - spring-boot

Basically, I am sending two parameters , one a String and the other a file to my controller in Spring Boot . In the action, when I receive the file first and then the String next, like so
#RequestMapping(value = "/updatemedia", method = RequestMethod.PATCH,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> updateMedia(#RequestParam(value ="file") MultipartFile fileToUpload , #RequestParam(value = "keyId") String keyId )
everything is fine and I am able to access the String and the file correctly.
But when I change the order of the parameters , like so
#RequestMapping(value = "/updatemedia", method = RequestMethod.PATCH,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> updateMedia( #RequestParam(value = "keyId") String keyId , #RequestParam(value ="file") MultipartFile fileToUpload )
and send the params through Postman, I am hitting the below error
I researched a lot but am not able to understand this behaviour.

Because you send keyId in body while it's declared as #RequestParam
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html .
#RequestParam has nothing to deal with request body, it's passed in request url.
What about your example, the first approach works, because your method expects one #RequestPart, the others are ignored.

Related

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.

Send email with multiple attachments in Spring boot

I'm creating an api for sending email in Spring Boot. I can successfully send an attachment in email using the following api
#PostMapping("/send")
public void sendMail(#RequestParam(value = "receiver") String receiver,
#RequestParam(value = "subject") String subject, #RequestParam(value = "content") String content,
#RequestParam(value = "file", required = false) MultipartFile file) {
mailService.send(receiver, subject, content, file);
}
But an email can have multiple attachments. So, using this link as the reference, I updated my code to
#PostMapping("/send")
public void sendMail(#RequestParam(value = "receiver") String receiver,
#RequestParam(value = "subject") String subject, #RequestParam(value = "content") String content,
#RequestParam(value = "files", required = false) MultipartFile[] files) {
mailService.send(receiver, subject, content, files);
}
With this in place, I can add multiple images from the Swagger UI
Update:
I get the following form in Swagger from which I can upload images
But when I submit the form, I found that the value in files is now null instead of an array of files.
What am I missing?
As #MebinJoe mentioned, it was an issue with swagger. Couldn't solve the issue with swagger but ended up using Postman for testing the above piece of code. Multiple files were successfully attached and sent in email.

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

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.

Invoking service with #RequestParam and #RequestBody using postman client

Was trying to invoke the service
http://IP:8080/PQRS/LMN/XYZ/runTest/scheduledautomation/1/XYZ
with below JSON String
[ {"paramName":"TEST_TARGET_IDENTIFIER","paramValue":"ETest"},{"paramName":"TEST_SOURCE_ENTRY_IDENTIFIER","paramValue":"com.pack.etest"}]
#ResponseStatus(value = HttpStatus.NO_CONTENT)
#RequestMapping(value = "/runTest/scheduledautomation/{runId}/{testEngine}", method = RequestMethod.POST)
public void runScheduledAutomatedTest(#RequestParam String cronExpresssion,
#RequestParam(required = false) #DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime endTime,
#PathVariable Integer runId,
#PathVariable TestEngine testEngine,
#RequestBody List<TestEngineParam> testEngineParams) throws Exception { //Some Code }
Response :
Required String parameter 'cronExpresssion' is not present
how to invoke mixed #RequestParam and #RequestBody services on postman client ?
I fear you want a little bit too much: RequestParam, RequestBody AND the whole thing as a REST query. At least two of the three things are mutually exclusive.
I think you could even get Postmaster to do this by modifying the called URL to:
http://IP:8080/PQRS/LMN/XYZ/runTest/scheduledautomation/1/XYZ?cronExpression=your-expression
Of course this would ruin your REST interface, but as I said: your handler method is a little bit "over-ambitious".

Resources