SpringMVC3️⃣请求:文件上传

回顾Java Web文件上传

  1. 浏览器处理上传文件,将文件以的形式提交到服务器端

    • commons-fileupload:Apache 的文件上传组件,取代原生的文件上传流。
    • commons-io:commons-fileupload 组件依赖于该组件。
  2. 客户端表单三要素

    • 提交方式method="post"
    • 编码类型enctype="multipart/form-data"
    • 文件表单项

SpringMVC 文件上传

  • 更简单的封装
  • 即插即用

1、说明

服务器端收到请求时,DispatcherServlet 的 checkMultipart() 调用 MultipartResolver 的 isMultiPart(),判断请求中是否包含文件上传控件。

  • 若请求数据中包含文件
    • 调用 MultipartResolver 的 resolveMultipart() 来解析请求数据。
    • 将文件数据解析成 MultipartFile,封装成 MultipartHttpServletRequest 对象。
    • 传递给 Controller。
  • MultipartFile
    • 此时这个文件存储在内存中或临时的磁盘文件中。
    • 需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。

2、API

MultipartResolver 类

类似原来的 ServletFileUpload

  • isMultipart():对应 ServletFileUpload 类的isMultipartContent()

  • resolveMultipart():对应 ServletFileUpload 类的parseRequest()

  • cleanupMultipart():对应 DiskFileItem 类的delete()

    // 判断请求是否包含文件上传控件
    boolean isMultipart(HttpServletRequest request); 
    // 解析请求
    MultipartHttpServletRequest resolveMultipart(HttpServletRequest request); 
    // 清除主题内容
    void cleanupMultipart(MultipartHttpServletRequest request);
    

MultipartFile 类

类似原来的 FileItem 类

  • getName()

  • getOriginalFilename()

  • getContentType()

    // 获取参数的名称
    String getName(); 
    // 获取上传文件名
    String getOriginalFilename(); 
    // 获取文件内容的类型
    String getContentType(); 
    // 判断文件是否为空
    boolean isEmpty();
    // 获取文件大小
    long getSize();
    // 将文件内容以字节数组的形式返回
    byte[] getBytes();
    // 获取文件输入流:将文件内容以输入流的形式返回
    InputStream getInputStream(); 
    // 将上传文件内容保存到指定目录文件中
    void transferTo(File dest); 
    

3、使用

开发步骤

  1. 导入依赖
  2. 配置文件上传解析器
  3. 编写 Controller

3.1、环境搭建

  1. 导入 commons-fileupload:Maven 会自动导入它的依赖包 commons-io

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    
  2. 配置文件上传解析器:id 必须为 multipartResolver

    • 上传文件的编码类型:需与客户端页面编码格式相同

    • 上传文件总大小:单位 byte

    • 上传单个文件的大小:单位 byte

    • 缓存文件的最大值:单位 byte

      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <property name="defaultEncoding" value="utf-8"/>
          <property name="maxUploadSize" value="10485760"/>
          <property name="maxUploadSizePerFile" value="1024"/>
          <property name="maxInMemorySize" value="40960"/>
      </bean>
      

3.2、单文件上传

表单

<form action="" method="post" enctype="multipart/form-data">
    用户<input type="text" name="username"><br>
    文件<input type="file" name="uploadFile"><br>
    <input type="submit">
</form>

CommonsMultipartFile:封装请求参数中的文件。

主要步骤

  1. 获取上传文件名:getOriginalFilename()

  2. 设置上传文件的保存路径

  3. 保存文件transferTo()(也可使用 IO 流传输)

    @RestController
    public class FileController {
        @RequestMapping("/upload")
        public void upload(@RequestParam("uploadFile") CommonsMultipartFile file) throws IOException {
    		// 上传文件名
            String filename = file.getOriginalFilename();
    		// 保存路径
            File uploadPath = new File("F:\\temp");
            if (!uploadPath.exists()) {
                uploadPath.mkdir();
            }
    		// 保存文件
            file.transferTo(new File(uploadPath + "\\" + filename));
        }
    }
    

3.3、多文件上传

相比单文件上传

  1. 将 Controller 方法参数 CommonsMultipartFile 声明为数组类型。
  2. 遍历数组,其它操作相同。

表单

<form action="${pageContext.request.contextPath}/uploads" method="post" enctype="multipart/form-data">
    用户<input type="text" name="username"><br>
    文件<input type="file" name="uploadFiles"><br>
    文件<input type="file" name="uploadFiles"><br>
    文件<input type="file" name="uploadFiles"><br>
    <input type="submit">
</form>

CommonsMultipartFile:封装请求参数中的多个文件。

@RequestMapping("/uploads")
public void uploads(@RequestParam("uploadFiles") CommonsMultipartFile[] files) throws IOException {
    for (CommonsMultipartFile file : files) {
        // 上传文件名
        String filename = file.getOriginalFilename();
        // 保存路径
        File uploadPath = new File("F:\\temp");
        if (!uploadPath.exists()) {
            uploadPath.mkdir();
        }
        // 保存文件
        file.transferTo(new File(uploadPath + "\\" + filename));
    }
}
posted @ 2021-08-13 22:44  Jaywee  阅读(92)  评论(0编辑  收藏  举报

👇