简体   繁体   中英

How to get part of request body as input stream (request body mapped to multiple fields, one of them is an inputstream field)

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 eg 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!

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 class="exempt" style="border:none;">Add project</h2>
    <input class="exempt" th:field="*{title}" type="text">
    <textarea class="exempt" th:field="*{description}" rows="4"></textarea>



    <input class="exempt" type="hidden" th:field="*{videoName}" id="setVidName">
    <input class="exempt" type="file" id="vidName" accept="video/mp4" name="file" onchange="setNameVar(this);">
    <button class="exempt" 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM