概述
文件上传是项目开发中常用的功能之一,文件上传必须将表单的method设置为POST,并将enctype设置为multipart/form-data。
只有在这种情况下,浏览器才会把用户所选文件的二进制数据发送给服务器。
Apache发布了开源的Commons FileUpload组件,servlet3.0规则提供了相关方法处理文件上传,spring mvc则提供了更为简单的
封装。
spring mvc使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。但spring
mvc实现文件上传依然需要Apache Commons FileUpload组件。
springboot的spring-boot-starter-web已经集成了spring mvc,所以springboot实现文件上传则更为简单。
案例:springboot文件上传
pom.xml
由于Apache Commons FileUpload组件不属于springboot,所以需要添加依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
application.yml
springboot文件上传默认文件大小为1MB,超过1MB会报错,可以设置相关属性修改文件限制大小
spring:
servlet:
multipart:
#设置单个文件大小
max-file-size: 3MB
#设置总上传数据大小
max-request-size: 10MB
由于使用内置tomcat,不方便进行回显,所以通过设置文件上传位置及映射位置进行回显
#自定义属性
file:
upload:
#设置文件上传位置(绝对路径)
path: E:/temp/
#设置文件上传后回显位置(相对路径)
relative: /images/**
文件上传页面
在static目录下创建index.html页面 (在static目录下创建目的是可以直接访问该页面)
注意表单 method 提交方式为 post ,同时设置 enctype 属性值为 multipart/form-data
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<div>
<label>文件:</label>
<input type="file" name="attach">
</div>
<div>
<input type="submit">
</div>
</form>
</body>
</html>
控制器
package com.xiaomin.wechat_brn.controller;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
/**
* @author 晓敏
* @create 2020-04-01 14:33
*/
@Controller
public class UploadController {
//文件上传位置
@Value("${file.upload.path}")
private String filePath;
@RequestMapping("/upload")
public String upload(MultipartFile attach, Model model){
//判断文件是否为空,不为空则进行文件上传
if(!attach.isEmpty()){
//获取源文件名称
String fileName = attach.getOriginalFilename();
//获取源文件后缀名
String suffix = FilenameUtils.getExtension(fileName);
//使用UUID重命名文件名称
String newFileName= UUID.randomUUID().toString().replace("-","").toUpperCase()+"."+suffix;
//使用日期解决同一文件夹中文件过多问题(以当前日期命名文件夹)
String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//组装最终文件名
String finalName = datePath +"/" + newFileName;
//构建文件对象
File dest = new File(filePath +finalName);
//判断该文件夹是否存在,不存在则创建
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();//创建文件夹
}
try {
//将文件保存到硬盘
attach.transferTo(dest);
//将当前图片放到模型中,便于页面回显
model.addAttribute("image",finalName);
} catch (IOException e) {
e.printStackTrace();
}
}
//返回页面(该页面是templates目录下的页面)
return "show";
}
}
图片回显页面
在templates目录表创建show.html页面
注意:先在pom.xml文件中添加thymeleaf模板依赖,然后在application.yml文件中设置关闭thymeleaf缓存属性
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
spring:
#关闭thymeleaf缓存
thymeleaf:
cache: false
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>图片的回显</title>
</head>
<body>
<p th:text="${image}"></p>
<img th:src="@{/images/}+${image}">
</body>
</html>
文件上传配置类
新建UploadConfig类,实现WebMvcConfigurer接口, 配置资源映射路径
package com.xiaomin.wechat_brn.confing;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 晓敏
* @create 2020-04-02 10:56
*/
public class UploadConfig implements WebMvcConfigurer {
/**上传地址*/
@Value("${file.upload.path}")
private String filePath;
/**显示相对地址*/
@Value("${file.upload.path.relative}")
private String fileRelativePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(fileRelativePath)
//读取本地文件需要加上file:/
.addResourceLocations("file:/"+filePath);
}
}
测试