互联网行业中上传文件是一个高频的使用场景,常用的案例有上传头像、上传身份证信息等。Spring Boot利用MultipartFile的特性来接收和处理上传的文件,MultipartFile是Spring封装的接口,封装了文件上传的相关操作,利用MultipartFile可以方便地接收前端文件,将接收到的文件存储到本机或者其他中间件中。
一、Spring Boot文件上传
A、相关依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
B、配置信息
spring.thymeleaf.cache=false
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
# 支持的最大文件
spring.servlet.multipart.max-file-size=200MB
# 文件请求最大限制
spring.servlet.multipart.max-request-size=200MB
# multipart上传文件
spring.servlet.multipart.enabled=true
# 上传文件的临时目录
#spring.servlet.multipart.location=
# multipart上传文件时懒加载
#spring.servlet.multipart.resolve-lazily=false
对静态资源进行配置。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer
{
/** * 静态资源加载配置 */
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
以上配置主要是通过设置thymeleaf以及MultipartFile的属性来控制上传限制,MultipartFile 是Spring上传文件的封装类,包含了文件的二进制流和文件属性等信息,在配置文件中也可对相关属性进行配置。
C、前端页面
1、单文件
<html xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>file uploadtitle><link href="/static/bootstrap.css" rel="stylesheet" type="text/css"/><link href="/static/common.css" rel='stylesheet' type='text/css'/>head><body><p>Spring Boot文件上传p><form action="/file_upload" method="post" enctype="multipart/form-data"><input type="file" name="file"/><input type="submit" value="文件上传"/>form>body>html>
2、多文件
<html xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>file uploadtitle><link href="/static/bootstrap.css" rel="stylesheet" type="text/css"/><link href="/static/common.css" rel='stylesheet' type='text/css'/>head><body><p>Spring Boot文件上传p><form action="/multi_file_upload" method="post" enctype="multipart/form-data">
文件1 : <input type="file" name="file" /><br/><br/>
文件2 : <input type="file" name="file" /><br/><br/>
文件3 : <input type="file" name="file" /><br/><br/><input type="submit" value="文件上传" />form>body>html>
3、上传结果
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>file upload resulttitle><link href="/static/bootstrap.css" rel="stylesheet" type="text/css"/><link href="/static/common.css" rel='stylesheet' type='text/css'/>head><body><div th:if="${message}"><h3 th:text="${message}"/>div>body>html>
D、Controller
@Controller
public class UploadController
{
private static String UPLOADED_FOLDER = "E:\\D\\spring-boot-study\\web-file-upload\\src\\main\\resources\\file_upload\\";
@GetMapping("/upload")
public String index()
{
return "upload";
}
@GetMapping("/multi")
public String uploadMore()
{
return "multiupload";
}
@GetMapping("/uploadResult")
public String uploadStatus()
{
return "uploadresult";
}
@PostMapping("/file_upload")
public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes)
{
if (file.isEmpty())
{
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadResult";
}
try
{
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
Files.write(path, bytes);
redirectAttributes.addFlashAttribute("message", "Successfully uploaded '" + file.getOriginalFilename() + "'");
}
catch (IOException e)
{
e.printStackTrace();
}
return "redirect:/uploadResult";
}
@PostMapping("/multi_file_upload")
public String moreFileUpload(@RequestParam("file") MultipartFile[] files, RedirectAttributes redirectAttributes)
{
if (files.length == 0)
{
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadResult";
}
for (MultipartFile file : files)
{
try
{
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
Files.write(path, bytes);
}
catch (IOException e)
{
e.printStackTrace();
}
}
redirectAttributes.addFlashAttribute("message", "Successfully uploaded all");
return "redirect:/uploadResult";
}
}
E、异常处理
@ControllerAdvice
public class GlobalExceptionHandler
{
@ExceptionHandler(MultipartException.class)
public String handleError1(MultipartException e, RedirectAttributes redirectAttributes)
{
redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
return "redirect:/uploadResult";
}
}
对MultipartException的异常处理,稍微改造则可以监控整个项目的异常问题。
之前在改造github.com/isisiwish/bo项目时,已经用了Spring文件上传和Spring Framework时期并没有太多区别,所以这里只做简单记录总结。
上面项目中的的IFileService提供将上传的文件继续上传至七牛云,返回图片URL,具体可以参看github。
public interface IFileService
{
String upload(MultipartFile file, String path);
}
二、总结
Spring Boot完美支持文件上传,不论是单个文件上传还是多个文件上传都很简单。在上传文件的过程中也可以通过配置文件来选择关闭或者限制上传文件大小,利用@ControllerAdvice可以灵活地对异常进行全局处理。
公众号:架构师之巅扫码关注最前沿的技术