Home  >  Article  >  Java  >  How SpringBoot implements file upload and download functions

How SpringBoot implements file upload and download functions

WBOY
WBOYforward
2023-05-16 08:46:121337browse

Spring Boot file upload and download

In actual web application development, in order to successfully upload files, the method of the form must be set to post and the enctype must be set to multipart/form-data. Only with this setting can the browser send the binary data of the selected file to the server.

Starting from Servlet 3.0, methods for handling file uploads have been provided, but this file upload needs to be completed in Java Servlet, and Spring MVC provides a simpler encapsulation. Spring MVC implements a MultipartResolver implementation class CommonsMultipartResolver through Apache Commons FileUpload technology to complete file upload. Therefore, Spring MVC's file upload needs to rely on the Apache Commons FileUpload component.

Spring MVC automatically binds the uploaded file to the MultipartFile object. MultipartFile provides methods to obtain the uploaded file content, file name, etc., and uploads the file to the server's disk through the transferTo method. The common methods of MultipartFile are as follows :

  • #byte[] getBytes(): Get file data.

  • String getContentType(): Get the file MIME type, such as image/jpeg, etc.

  • InputStream getInputStream(): Get the file stream.

  • String getName(): Get the name of the file component in the form.

  • String getOriginalFilename(): Get the original name of the uploaded file.

  • long getSize(): Get the byte size of the file, in byte.

  • boolean isEmpty(): Whether there is (selected) upload file.

  • void transferTo(File dest): Save the uploaded file to a target file.

Spring Boot's spring-boot-starter-web has integrated Spring MVC, so it is more convenient to use Spring Boot to upload files. You only need to introduce the Apache Commons FileUpload component dependency.

Example

The following explains the implementation process of Spring Boot file upload and download through an example.

[Example 7] Spring Boot file upload and download.

The specific implementation steps are as follows.

1. Introduce the Apache Commons FileUpload component dependency

In the pom.xml file of the web application ch7_2, add the Apache Commons FileUpload component dependency. The specific code is as follows:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <!-- 由于commons-fileupload组件不属于Spring Boot,所以需要加上版本 -->
    <version>1.4</version>
</dependency>

2 .Set the upload file size limit

In the configuration file application.properties of the web application ch7_2, add the following configuration to limit the upload file size.

#上传文件时,默认单个上传文件大小是1MB,max-file-size设置单个上传文件大小
spring.servlet.multipart.max-file-size=50MB
#默认总文件大小是10MB,max-request-size设置总上传文件大小
spring.servlet.multipart.max-request-size=500MB

3. Create the file selection view page

In the src/main/resources/templates directory of the ch7_2 application, create the file selection view page uploadFile.html. There is a form form with the enctype attribute value multipart/form-data in this page. The specific code is as follows:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{css/bootstrap.min.css}" />
<!-- 默认访问 src/main/resources/static下的css文件夹-->
<link rel="stylesheet" th:href="@{css/bootstrap-theme.min.css}" />
</head>
<body>
<div class="panel panel-primary">
    <div class="panel-heading">
      <h4 class="panel-title">文件上传示例</h4>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <div class="col-md-6 col-sm-6">
        <form class="form-horizontal" action="upload" 
method="post" enctype="multipart/form-data">
          <div class="form-group">
            <div class="input-group col-md-6">
              <span class="input-group-addon">
                <i class="glyphicon glyphicon-pencil"></i>
              </span>
              <input class="form-control" type="text"
               name="description" th:placeholder="文件描述"/>
            </div>
          </div>
          <div class="form-group">
            <div class="input-group col-md-6">
              <span class="input-group-addon">
                <i class="glyphicon glyphicon-search"></i>
              </span>
              <input class="form-control" type="file"
               name="myfile" th:placeholder="请选择文件"/>
            </div>
          </div>
          <div class="form-group">
            <div class="col-md-6">
              <div class="btn-group btn-group-justified">
                <div class="btn-group">
                  <button type="submit" class="btn btn-success">
                    <span class="glyphicon glyphicon-share"></span>
                     上传文件
                  </button>
                </div>
              </div>
            </div>
          </div>
        </form>
      </div>
    </div>
  </div>
</body>
</html>

4. Create the controller

in com.ch.ch7_2 applied in ch7_2. In the controller package, create the controller class TestFileUpload. There are 4 processing methods in this class, one is the interface navigation method uploadFile, one is the upload method to implement file upload, one is the showDownLoad method to display the file to be downloaded, and the other is the download method to implement the download function. The core code is as follows:

@Controller
public class TestFileUpload {
  @RequestMapping("/uploadFile")
  public String uploadFile() {
    return "uploadFile";
  }
  /**
   * 上传文件自动绑定到MultipartFile对象中,
   * 在这里使用处理方法的形参接收请求参数。
     */
  @RequestMapping("/upload")
  public String upload(
      HttpServletRequest request,
      @RequestParam("description") String description,
      @RequestParam("myfile") MultipartFile myfile)
throws IllegalStateException, IOException {
    System.out.println("文件描述:" + description);
    //如果选择了上传文件,将文件上传到指定的目录uploadFiles
    if(!myfile.isEmpty()) {
      //上传文件路径
      String path = request.getServletContext().getRealPath("/uploadFiles/");
      //获得上传文件原名
      String fileName = myfile.getOriginalFilename();
      File filePath = new File(path + File.separator + fileName);
      //如果文件目录不存在,创建目录
      if(!filePath.getParentFile().exists()) {
        filePath.getParentFile().mkdirs();
      }
      //将上传文件保存到一个目标文件中
      myfile.transferTo(filePath);
    }
    //转发到一个请求处理方法,查询将要下载的文件
    return "forward:/showDownLoad";
  }
  /**
   * 显示要下载的文件
   */
  @RequestMapping("/showDownLoad")
  public String showDownLoad(HttpServletRequest request, Model model) {
    String path = request.getServletContext().getRealPath("/uploadFiles/");
    File fileDir = new File(path);
    //从指定目录获得文件列表
    File filesList[] = fileDir.listFiles();
    model.addAttribute("filesList", filesList);
    return "showFile";
  }
  /**
   * 实现下载功能
   */
  @RequestMapping("/download")
  public ResponseEntity<byte[]> download(
      HttpServletRequest request,
      @RequestParam("filename") String filename,
      @RequestHeader("User-Agent") String userAgent) throws IOException {
    //下载文件路径
    String path = request.getServletContext().getRealPath("/uploadFiles/");
    //构建将要下载的文件对象
    File downFile = new File(path + File.separator + filename);
    //ok表示HTTP中的状态是200
    BodyBuilder builder = ResponseEntity.ok();
    //内容长度
    builder.contentLength(downFile.length());
    //application/octet-stream:二进制流数据(最常见的文件下载)
    builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
    //使用URLEncoder.encode对文件名进行编码
    filename = URLEncoder.encode(filename,"UTF-8");
    /**
     * 设置实际的响应文件名,告诉浏览器文件要用于“下载”和“保存”。
     * 不同的浏览器,处理方式不同,根据浏览器的实际情况区别对待。
     */
    if(userAgent.indexOf("MSIE") > 0) {
      //IE浏览器,只需要用UTF-8字符集进行URL编码
      builder.header("Content-Disposition", "attachment; filename=" + filename);
    }else {
      /**非IE浏览器,如FireFox、Chrome等浏览器,则需要说明编码的字符集
       * filename后面有个*号,在UTF-8后面有两个单引号
       */
      builder.header("Content-Disposition", "attachment; filename*=UTF-8&#39;&#39;" + filename);
    }
    return builder.body(FileUtils.readFileToByteArray(downFile));
  }
}

5. Create a file download view page

In the src/main/resources/templates directory of the ch7_2 application, create a file download view page showFile.html. The core code is as follows:

<body>
  <div class="panel panel-primary">
    <div class="panel-heading">
      <h4 class="panel-title">文件下载示例</h4>
    </div>
  </div>
  <div class="container">
    <div class="panel panel-primary">
      <div class="panel-heading">
        <h4 class="panel-title">文件列表</h4>
      </div>
      <div class="panel-body">
        <div class="table table-responsive">
          <table class="table table-bordered table-hover">
            <tbody class="text-center">
              <tr th:each="file,fileStat:${filesList}">
                <td>
                  <span th:text="${fileStat.count}"></span>
                </td>
                <td>
                <!--file.name相当于调用getName()方法获得文件名称 -->
                  <a th:href="@{download(filename=${file.name})}">
                    <span th:text="${file.name}"></span>
                  </a>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</body>

6. Run

First, run the Ch72Application main class. Then, visit http://localhost:8080/ch7_2/uploadFile to test file upload and download.

The above is the detailed content of How SpringBoot implements file upload and download functions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete