SpringBoot文件上传
SpringMVC对文件上传做了简化,在SpringBoot中对此做了更进一步的简化,文件上传更加方便。
Java中的文件上传一共涉及两个组件,一个是CommonsMultipartResolver,另一个是StandardServletMultipartResolver,其中CommonsMultipartResolver使用commons-fileupload来处理multipart请求,而StandardServletMultipartResolver则是基于Servlet 3.0 来处理multipart请求的。因此若使用StandardServletMultipartResolver,则不需要添加额外的jar包。
Tomcat 7.0 开始就支持Servlet 3.0 了,而SpringBoot 2.04 内嵌的Tomcat为Tomcat 8.5.32,因此可以直接使用 StandardServletMultipartResolver。
而在SpringBoot提供的文件上传自动化配置类MultipartAutoConfiguration中,默认也是采用StandardServletMultipartResolver,部分源码如下:
@Bean(
name = {"multipartResolver"}
)
@ConditionalOnMissingBean({MultipartResolver.class})
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
根据配置可以看出,如果我们没有提供MultipartResolver,那么默认采用的MultipartResolver就是StandardServletMultipartResolver。
在配置文件中对文件上传进行详细配置:
spring.servlet.multipart.enabled=true #是否支持开启文件上传支持,默认为true
spring.servlet.multipart.file-size-threshold=0 #文件写入磁盘的阈值,默认为0
spring.servlet.multipart.location=E:\\temp #设置上传文件的临时保存位置
spring.servlet.multipart.max-file-size=1MB #上传文件的最大大小,默认为1MB
spring.servlet.multipart.min-request-size=10MB #多文件上传时文件的总大小,默认为10MB
spring.servlet.multipart.resolve-lazily=false #是否延迟解析,默认为false
页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="请选择文件">
<input type="submit" value="上传">
</form>
</body>
</html>
controller:
@PostMapping("/upload")
public String upload2(MultipartFile uploadFile, HttpServletRequest request){
if(uploadFile.isEmpty()){
//返回选择文件提示
return "请选择上传文件";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//构建文件上传所要保存的"文件夹路径"--这里是相对路径,保存到项目根路径的文件夹下
String realPath = new String("src/main/resources/" + UPLOAD_PATH_PREFIX);
logger.info("-----------上传文件保存的路径【"+ realPath +"】-----------");
String format = sdf.format(new Date());
//存放上传文件的文件夹
File file = new File(realPath + format);
logger.info("-----------存放上传文件的文件夹【"+ file +"】-----------");
logger.info("-----------输出文件夹绝对路径 -- 这里的绝对路径是相当于当前项目的路径而不是“容器”路径【"+ file.getAbsolutePath() +"】-----------");
if(!file.isDirectory()){
//递归生成文件夹
file.mkdirs();
}
//获取原始的名字 original:最初的,起始的 方法是得到原来的文件名在客户机的文件系统名称
String oldName = uploadFile.getOriginalFilename();
logger.info("-----------文件原始的名字【"+ oldName +"】-----------");
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."),oldName.length());
logger.info("-----------文件要保存后的新名字【"+ newName +"】-----------");
try {
//构建真实的文件路径
File newFile = new File(file.getAbsolutePath() + File.separator + newName);
//转存文件到指定路径,如果文件名重复的话,将会覆盖掉之前的文件,这里是把文件上传到 “绝对路径”
uploadFile.transferTo(newFile);
String filePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/uploadFile/" + format + newName;
logger.info("-----------【"+ filePath +"】-----------");
return filePath;
} catch (Exception e) {
e.printStackTrace();
}
return "上传失败!";
}
配置静态资源映射:
-
问题:做完图片上传之后,根据返回的路径访问不到,重启了服务器,再次访问发现竟然可以了。不重启它就不能显示。
-
原因:这是因为对服务器的保护措施导致的,服务器不能对外部暴露真实的资源路径,需要配置虚拟路径映射访问。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
//配置静态虚拟路径
registry.addResourceHandler("/uploadFile/**").addResourceLocations("file:F:\\IDEAworkspace\\springboot_file\\src\\main\\resources\\static\\uploadFile\\");
}
测试:



本文详细介绍SpringBoot中文件上传的实现方法,包括使用StandardServletMultipartResolver处理multipart请求,配置文件上传参数,以及如何在Controller中接收并处理上传的文件。


被折叠的 条评论
为什么被折叠?



