Send email with multiple attachments in Spring boot - 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.

Related

Swagger: How to use password format (Parameter annotation) for a String field ? Currently it won't allow me to submit the form with a value

I have a Spring Boot app (2.7.0) with spring docs (1.6.9)
Endpoint defined as follows:
#PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
#Operation(summary = "blah blah blah")
public ResponseEntity<UploadSummary> uploadData(
#RequestParam("file") final MultipartFile csvFile,
#Parameter(schema = #Schema(type = "string", format = "password"))
#RequestParam("password") final String password,
#RequestParam(name = "dryRun", required = false, defaultValue = "true") final boolean dryRun) {
I want to have the password input field on the Swagger interface mask the input. The only change I have made above is to include a single #Parameter annotation, nothing else.
The Swagger interface does not appear to like this single Parameter annotation at all, regardless of format. If I input a value in the password field, it is always highlighted with a red border and I cannot execute.
I tried upgrading to 1.6.12 but still doesn't work.
Perhaps other annotations or code needs to be setup before these Parameter annotations and Schema types work ?

SpringBoot reject all request if some header parms are not there even if we don't include them in specific requests

An example of that is below. I am not using associateId, firstName, lastName and galleryId but I want this request to be rejected if they are not present (Below code works for this). But is there a common place where we can set it for all request by default and not have to repeat the below code for all request?
#ApiOperation("Delete Project")
#DeleteMapping(value = "{projectId}")
public void deleteProject(
#ApiParam(value = "Project Id to be deleted", required = true) #PathVariable String projectId,
#RequestHeader("associateId") String associateId,
#RequestHeader("associateFirstName") String firstName,
#RequestHeader("associateLastName") String lastName,
#RequestHeader("galleryId") String galleryId) {
pjs.deleteProject(projectId);
}
I have lot of endpoints and only few use all 4 header variables but I want all request to have access to them even if they are not using them.

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 boot: Upload several MultipartFile with several additional data

I need to create an endpoint that:
Receives N ItemType.
Receive 1 GroupType.
Each ItemType has:
attributes.
MultipartFile.
GroupType only contains attributes.
public class ItemType {
private String description;
private String security;
private Date bestdate;
private MultipartFile content;
}
public class GroupType {
private String description;
private String security;
private String metadata;
}
So, my endpoint would be something like:
public ResponseEntity<String> group(
List<ItemType> items,
GroupType group);
I don't know if it's the best approach. Some thinks comes up with this approach:
What about GroupType.security and ItemType.security?
What about MultiPart files?
How might this endpoint be called?
Any ideas?
Here is a solution using Multipart-FormData.
Enabling multipart properties:
# MULTIPART (MultipartProperties)
spring.servlet.multipart.enabled=true # Enable multipart uploads
spring.servlet.multipart.max-file-size=200MB # Max file
spring.servlet.multipart.max-request-size=215MB # Max Request Size
Controller:
#PostMapping(consumes = "multipart/form-data")
public ResponseEntity<String> uploadWithData(
#RequestPart("itemTypes") List<ItemType> ,
#RequestPart("group") Group group
#RequestPart MultipartFile[] file) {
// your code
}
ItemType will contain filename field to allow linking of ItemType to the uploaded file.

Multipartfile parameter order precedence causing error

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.

Resources