Spring MVC file upload and download

Spring MVC file upload and download

File upload and download are frequently used functions in Web projects. Spring MVC can well support file upload and download; This section creates a new SpringMVC-09-File project. Learn to upload and download files in SpringMVC.

1. File upload

1.1 pre knowledge

File upload is to transfer data from the client to the server, so file transfer support is also required on the client!

The enctype attribute in the form of the front page is used to set the transmission format

  • Application / x-www = form urlencoded: by default, only the value attribute value in the form field is processed. Forms with this encoding method will process the value in the form field into URL encoding.
  • Multipart / form data: this encoding method will process form data in the form of binary stream. This encoding method will also encapsulate the contents of the file specified in the file field into the request parameters, and will not encode characters (i.e. use it).
  • text/plain: except for converting spaces to "+" signs, other characters are not encoded. This method can be used to send mail directly through forms.
<form action="" enctype="multipart/form-data" method="post">
   <input type="file" name="file"/>
   <input type="submit">
</form>

After setting the enctype to multipart / form data, the browser will process the form data in the form of binary stream to realize file transmission.

On the back end, you can also receive file uploads using Servlet (skipped before) 😓), However, spring MVC provides a simpler encapsulation, that is, it is implemented using MultipartResolver; Spring MVC implements a MultipartResolver implementation class, CommonsMultipartResolver, using Apache Commons FileUpload technology. Therefore, to upload files using spring MVC, you also need to import the package of Apache Commons FileUpload.

    <!--File upload-->
    <dependency>
       <groupId>commons-fileupload</groupId>
       <artifactId>commons-fileupload</artifactId>
       <version>1.3.3</version>
    </dependency>

After understanding the above content, you can try to upload the file!

1.2 basic operation

After creating a new spring MVC project, you still need to configure Web, spring MVC, Tomcat, etc., which are also omitted here.

Configure the bean of multipartResolver in the configuration file of spring MVC, and use the Commons multipartResolver implementation of spring MVC!

    <!--File upload configuration-->
    <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- The encoding format of the request must be and jSP of pageEncoding Property is consistent so that the contents of the form can be read correctly. The default is ISO-8859-1 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- Maximum upload file size, in bytes (10485760)=10M) -->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>

On the front page of the upload file, the enctype attribute is set to multipart / form data

<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="Upload file">
</form>

The controller method for processing the upload file request. After obtaining the file input stream, the output stream is output to the save path. It is the most basic IO operation

@Controller
public class FileController {

    @RequestMapping("/upload")
    // @RequestParam("file") encapsulates the file obtained by the name=file control into a CommonsMultipartFile object
    // When uploading files in batches, CommonsMultipartFile can be an array
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        // Get the file name file.getOriginalFilename()
        String uploadFileName = file.getOriginalFilename();

        // If the file name is empty, go back to the home page directly!
        if ("".equals(uploadFileName)) {
            return "redirect:/index.jsp";
        }
        System.out.println("Upload file name: " + uploadFileName);

        // Get the current project path and set the upload file saving path
        String path = request.getServletContext().getRealPath("/upload");
        System.out.println("path: " + path);
        // If the save path does not exist, create one
        File realPath = new File(path);
        if (!realPath.exists()) {
            realPath.mkdir();
        }
        System.out.println("Upload file storage address:" + realPath);

        // File input stream
        InputStream is = file.getInputStream();
        // File output stream
        OutputStream os = new FileOutputStream(new File(realPath, uploadFileName));

        // IO operation
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
}

CommonsMultipartFile, that is, two methods of file object, are used

  • String getOriginalFilename(): get the original name of the uploaded file
  • InputStream getInputStream(): get file stream

Through these two methods, the name and data of the file are obtained, and then the output stream is saved to the server! The test upload file is saved in the upload folder of the corresponding project under the out folder!

1.3 simplified operation

Although the above file upload is successfully realized, there are still abstractable parts in the code, such as obtaining file name, obtaining input stream and saving file. The operations should be the same for any file; Therefore, CommonsMultipartFile provides the transferTo method to save the file directly!

Add another method to handle file upload in the controller, corresponding to request / upload2

@Controller
public class FileController {
    ...

    // Using the transferTo method is simpler
    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        // Get the current project path and set the upload file saving path
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()) {
            realPath.mkdir();
        }
        System.out.println("Upload file storage address:" + realPath);

        // Use the transferTo method of CommonsMultipartFile to write the file directly!
        file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));

        return "redirect:/index.jsp";
    }
}

The transferTo method of CommonsMultipartFile eliminates the steps of judging whether the file is empty and performing IO operation. As long as there is a file name and save path, it can be directly in place in one step!

2. File download

File downloading is much easier than uploading, because the client only needs to receive data as usual, but only binary data!

For the corresponding front-end page, just launch a request as usual!

<a href="${pageContext.request.contextPath}/download">Download File</a>

Add a method to handle the download file request in the controller

@Controller
public class FileController {
    ...

    @RequestMapping(value = "/download")
    public String downloads(HttpServletResponse response, HttpServletRequest request) throws Exception {
        // 1. Set the path of the file to be downloaded
        String path = request.getServletContext().getRealPath("/upload");
        String fileName = "Irror.jpg";

        // 2. Set the response header
        // Set the page not to be cached, and clear the buffer
        response.reset();
        // Set character encoding
        response.setCharacterEncoding("UTF-8");
        // Set binary transfer data
        response.setContentType("multipart/form-data");
        // Set response header
        response.setHeader("Content-Disposition",
                "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));

        // 3. Get the file object to download
        File file = new File(path, fileName);
        // 4. Get the input stream of the file to be downloaded
        InputStream is = new FileInputStream(file);
        // 5. Obtain the output stream transmitted to the client (from the response)
        OutputStream os = response.getOutputStream();

        // 6. Perform IO operation
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = is.read(buff)) != -1) {
            os.write(buff, 0, len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
}

It can be summarized into six steps

  1. Set the path of the file to download
  2. Set response header
  3. Get the file object to download
  4. Gets the input stream of the file to download
  5. Get the output stream transmitted to the client (from response)
  6. Perform IO operation

Run the test and download the file successfully! It's so simple that there's nothing to say!

3. Summary

In fact, there is nothing to summarize in this section. They are all common operations. To sum up, the learning of spring MVC has come to an end. It is inevitable to end with some emotion before departure. I don't know what to say for a while. I can only hope it will be better and better in the future 😭!

In this way, we live here and keep parting.

so leben wir und nehmen immer Abschied.

Tags: Spring Spring MVC mvc

Posted on Mon, 06 Sep 2021 23:37:58 -0400 by dai.hop