spring-mvc之文件上传与下载
配置
spring-boot中,起步依赖自动添加了需要的库,并自动配置了
MultipartResolver解析器,所以这步只针对直接使用spring的情况
spring-webmvc基于Apache提供的2个库实现文件的上传与下载
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
配置MultipartResolver组件
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
文件上传
官方文档参考
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-multipart-forms
Spring中文件上传的核心是使用 MultipartFile 类型的参数接收文件数据。
MultipartFile提供了以下常用方法
boolean isEmpty()- 判断表单文件是否为空String getOriginalFilename();- 获取文件名String getContentType()- 获取文件类型long getSize()- 获取文件大小byte[] getBytes()- 将文件转换为字节数组InputStream getInputStream()- 将文件转换为输入流void transferTo(File dest)- 文件保存的快捷方式void transferTo(Path dest)
另外,spring-boot文件上传默认配置中,单文件限制大小为1MB,单次请求文件总大小限制为10MB,可以使用以下方式修改默认值
spring:
servlet:
multipart:
enabled: true
max-file-size: 2MB # 单文件大小限制
max-request-size: 10MB # 文件总大小限制
单文件上传示例
HTML表单
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上传</button>
</form>
控制器代码
@PostMapping("/file/upload")
@ResponseBody
public String uploadFile(@RequestParam("file")MultipartFile file)
{
if(!file.isEmpty())
{
String fileName=file.getOriginalFilename();
String basePath="/home/lyp/Projects/spring-boot/web/src/main/resources/res";
try
{
File f=new File(basePath,fileName);
file.transferTo(f);
return "上传成功";
}
catch(IOException e)
{
e.printStackTrace();
}
}
return "上传失败";
}
多文件上传示例
HTML表单
<form action="/files/upload" method="post" enctype="multipart/form-data">
<input type="file" name="files" multiple>
<button type="submit">上传</button>
</form>
控制器中只需要接收MultipartFile数组或List即可
@PostMapping("/files/upload")
@ResponseBody
public String uploadFiles(@RequestParam("files") List<MultipartFile> files)
{
String basePath = "/home/lyp/Projects/spring-boot/web/src/main/resources/res";
try
{
for(MultipartFile file: files)
{
if(!file.isEmpty())
{
String fileName = file.getOriginalFilename();
File f = new File(basePath,fileName);
file.transferTo(f);
}
}
return "上传成功";
}
catch(IOException e)
{
e.printStackTrace();
}
return "上传失败";
}
文件下载
使用Servlet相关的API即可,唯一需要注意的是设置响应头信息
这里测试图片在res目录下,客户端之所以直接从根路径访问而不用加res前缀,是因为额外将res目录配置到spring-boot的静态资源查找路径中了。
配置方法就是使用static-locations选项。
HTML代码
<img src="/test.png" alt="">
<a href="/file/download?filename=test.png">下载</a>
控制器代码
@GetMapping("/file/download")
@ResponseBody
public String download(@RequestParam("filename") String filename,
HttpServletResponse resp)
{
if(filename!=null && !filename.isBlank())
{
String basePath = "/home/lyp/Projects/spring-boot/web/src/main/resources/res";
File file=new File(basePath,filename);
if(file.exists())
{
resp.setContentType("application/forc-download");
resp.setHeader("Content-Disposition","attachment;filename="+filename);
try(ServletOutputStream out=resp.getOutputStream();)
{
Path path=Path.of(file.toURI());
byte[] bytes = Files.readAllBytes(path);
out.write(bytes);
out.flush();
return "下载成功";
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
return "下载失败";
}

浙公网安备 33010602011771号