Let's consider following scenario:
I need to upload very large file, other than that I need the name, version and author. I have created the following endpoint:
@PostMapping(path = "/upload", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> upload(@RequestBody MyClass myClass) {
//do the upload using the content received as InputStream and return success
}
The MyClass.java:
public class MyClass {
private String name;
private String version;
private String author;
private InputStream fileContent;
// constructor, getters and setters
}
Example request body:
{
"name": "article",
"version": "1",
"author": "John Smith"
"fileContent": "ZmlsZUNvbnRlbnQg" //base64 encoded tgz/zip
}
So the whole case is to save the name,version and author e.g. in database, and then use the fileContent InputStream to stream it somewhere (as it is too big to have it as bytearray). Is something like that possible in spring? All help appreciated!
CodePudding user response:
I have this function for uploading videos to a directory in my intellij workspace.
@RequestMapping(method = RequestMethod.POST, path = "/projects/save/video")
public String uploadVideo(@RequestParam("file") MultipartFile file, @ModelAttribute Project project) throws InterruptedException {
// check if file is empty
if (file.isEmpty()) {
System.out.println("No file");
return "redirect:/user/projects";
}
// normalize the file path
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
// save the file on the local file system
try(InputStream inputStream = file.getInputStream()) {
Path path = Paths.get(VID_UPLOAD_DIR fileName);
Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
File directory = new File(CLASS_DIR);
if (! directory.exists()) {
directory.mkdir();
}
Path classPath = Paths.get(CLASS_DIR fileName);
Files.copy(path, classPath, StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e) {
e.printStackTrace();
}
String part="../videos/" fileName;
System.out.println(file.getSize() " <---[]---> " part);
member.setVideo(part);
MemberDB.projects.get(0).setTitle(project.getTitle());
MemberDB.projects.get(0).setDescription(project.getDescription());
MemberDB.projects.get(0).setLanguage(project.getLanguage());
MemberDB.projects.get(0).setTechnology(project.getTechnology());
MemberDB.projects.get(0).setVideoName(project.getVideoName());
return "redirect:/user/projects";
}
Template (using thymeleaf) looks like this
<form action="#" th:action="@{/projects/save/video}" name="subform" method="post" id="addProject" th:object="${project}" enctype="multipart/form-data">
<h2 style="border:none;">Add project</h2>
<input th:field="*{title}" type="text">
<textarea th:field="*{description}" rows="4"></textarea>
<input type="hidden" th:field="*{videoName}" id="setVidName">
<input type="file" id="vidName" accept="video/mp4" name="file" onchange="setNameVar(this);">
<button type="button" onclick="submitForm();">Save project</button>
</form>
And in your application properties
- spring.servlet.multipart.max-file-size=200MB
- spring.servlet.multipart.max-request-size=200MB
- spring.servlet.multipart.enabled=true