Spring MVC文件上传

1年前 (2024-04-28)
在实际的项目开发中,文件的上传和下载可以说是最常用的功能之一,例如图片的上传与下载、邮件附件的上传和下载等。本节我们将对 Spring MVC 中的文件上传功能进行讲解。

在 Spring MVC 中想要实现文件上传工作,需要的步骤如下。

1. 编写 form 表单

在 Spring MVC 项目中,大多数的文件上传功能都是通过 form 表单提交到后台服务器的。

form 表单想要具有文件上传功能,其必须满足以下 3 个条件。

  • form 表单的 method 属性必须设置为 post。

  • form 表单的 enctype 属性设置为 multipart/form-data。

  • 少提供一个 type 属性为 file 的 input 输入框。


常见的文件上传表单示例代码如下。

<form action="/upload" method="post" enctype="multipart/form-data">

<input type="file" name="fileName" multiple="multiple"/>

<input type="submit" value="上传">

</form>


当 form 表单的 enctype 属性为 multipart/form-data 时,浏览器会以二进制流的方式对表单数据进行处理,由服务端对文件上传的请求进行解析和处理。

在上面的代码中,除了满足文件上传表单所必须具备的 3 个条件外,<input> 标签中还增加了一个 multiple 属性。该属性可以让我们同时选择对个文件进行上传,即实现多文件上传功能。

2. 配置文件解析器(MultipartResolver )

Spring MVC 提供了一个名为 MultipartResolver 的文件解析器,来实现文件上传功能。MultipartResolver 本身是一个接口,我们需要通过它的实现类来完成对它的实例化工作。

MultipartResolver 接口共有两个实现类,如下表。

实现类

说明

依赖

支持的 Servlet 版本

StandardServletMultipartResolver

它是 Servlet 内置的上传功能。

不需要第三方 JAR 包的支持。

 仅支持 Servlet 3.0 及以上版本

CommonsMultipartResolver

借助 Apache 的 commons-fileupload 来完成具体的上传操作。

需要 Apache 的 commons-fileupload 等 JAR 包的支持。

不仅支持 Servlet 3.0 及以上版本,还可以在比较旧的 Servlet 版本中使用。


以上这两个 MultipartResolver 的实现类,无论使用哪一个都可以实现 Spring MVC 的文件上传功能。这里,我们以 CommonsMultipartResolver 为例进行讲解。

想要在 Spring MVC 中使用 CommonsMultipartResolver 对象实现文件上传,我们需要在 Spring MVC 的配置文件中对其进行以下配置。

<!--配置文件上传解析器-->

<bean id="multipartResolver" class="org.springframework.web.multipar网站站点" rel="nofollow" /> 注意:当我们在 Spring MVC 的配置文件中对 CommonsMultipartResolver 的 Bean 进行定义时,必须指定这个 Bean 的 id 为 multipartResolver,否则就无法完成文件的解析和上传工作。

3. 引入 Jar 包

由于 CommonsMultipartResolver 是 Spring MVC 内部通过 Apache Commons FileUpload 技术实现的,因此我们还需要将 Apache Commons FileUpload 组件的相关依赖引入到项目中。
  • commons-fileupload- . . .jar

  • commons-io-x.x.x.jar

注:点击上面的链接,即可下载相应的 JAR 包。

4. 编写控制器方法

在完成上面的所有步骤后,接下来,我们只需要在 Controller 中编写文件上传的方法即可实现文件的上传。

@Controller

public class FileUploadController {

@RequestMapping("/uplaod")

public String upload(MultipartFile file) {

if (!file.isEmpty()) {

return "success";

}

return "error";

}

}


在该控制器方法中包含一个 org.springframework.web.multipart.MultipartFile 接口类型的形参,该参数用来封装被上传文件的信息。MultipartFile 接口是 InputStreamSource 的子接口,该接口中提供了多个不同的方法,如下表。

名称

作用

byte[] getBytes()

以字节数组的形式返回文件的内容。

String getContentType()

返回文件的内容类型。

InputStream getInputStream()

返回一个 input 流,从中读取文件的内容。

String getName()

返回请求参数的名称。

String getOriginalFillename()

返回客户端提交的原始文件名称。

long getSize()

返回文件的大小,单位为字节。

boolean isEmpty()

判断被上传文件是否为空。

void transferTo(File destination)

将上传文件保存到目标目录下。

上传文件示例

下面,我们就通过一个实例,来演示下如何在 Spring MVC 中上传文件,具体步骤如下。

1. 新建一个名为 springmvc-file-demo 的 Web 工程,并将 Spring MVC 以及 Apache Commons FileUpload 相关的依赖导入到该工程中,web.xml 配置如下。

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp网站站点" rel="nofollow" />

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework网站站点" rel="nofollow" />

package net.biancheng.c.entity;

import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public class Student {

    //学号

    private String stuId;

    //姓名

    private String stuName;

    //年龄

    private Integer age;

    //用于接收后台上传的文件

    private List<MultipartFile> photos;

    //文件名称的字符串

    private String fileNameStr;

    //已上传图片的路径

    private List<String> path;

    public List<String> getPath() {

        return path;

    }

    public void setPath(List<String> path) {

        this.path = path;

    }

    public void setPhotos(List<MultipartFile> photos) {

        this.photos = photos;

    }

    public String getFileNameStr() {

        return fileNameStr;

    }

    public void setFileNameStr(String fileNameStr) {

        this.fileNameStr = fileNameStr;

    }

    public String getStuId() {

        return stuId;

    }

    public void setStuId(String stuId) {

        this.stuId = stuId;

    }

    public String getStuName() {

        return stuName;

    }

    public void setStuName(String stuName) {

        this.stuName = stuName;

    }

    public Integer getAge() {

        return age;

    }

    public void setAge(Integer age) {

        this.age = age;

    }

    public List<MultipartFile> getPhotos() {

        return photos;

    }

    @Override

    public String toString() {

        return "Student{" +

                "stuId='" + stuId + '\'' +

                ", stuName='" + stuName + '\'' +

                ", age=" + age +

                ", photos=" + photos +

                ", photoPath='" + fileNameStr + '\'' +

                ", path=" + path +

                '}';

    }

}


4. 在 webapp 下新建一个 js 目录,并将 jquery-3.6.0.min.js 添加进该目录下。

5. 在 webapp/WEB-INF 下新建一个 templates 目录,并在该目录下创建一个 file-upload.html ,代码如下。

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf网站站点" rel="nofollow" />

package net.biancheng.c.controller;

import net.biancheng.c.entity.Student;

import org.apac站站点" rel="nofollow" />

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf网站站点" rel="nofollow" />

图1:Spring MVC 图片上传-1


7. 在表单中分别填写学号、姓名、年龄等信息,然后点击“选择文件”按钮,如下图。

图2:点击选择文件


8. 选择需要上传的一张或多张图片,选择完成后,页面中回显了上传的图片,如下图。

图3:图片回显


9. 点击下方的提交按钮,将学生信息提交到后台,结果如下图。

springmvc 学生信息提交成功

图4:学生信息提交成功