Spring MVC 框架的文件上传基于 commons-fileupload 组件,在该组件上做了进一步的封装,简化了文件上传的代码实现,取消了不同上传组件上的编程差异。
相对于commons-fileupload原生的上传方式,程序员减少了DiskFileItemFactory,ServletFileUpload和将请求解析为FileItem的工作
通过Spring MVC 框架提供的MultipartResolver接口,它为文件上传提供了直接支持,用于处理上传请求,将上传请求包装成可以直接获取文件的数据,从而方便操作。
MultpartiResolver 接口有以下两个实现类:
- StandardServletMultipartResolver:使用了 Servlet 3.0 标准的上传方式。
- CommonsMultipartResolver:使用了 Apache 的 commons-fileupload 来完成具体的上传操作。
| 名称 | 作用 |
|---|---|
| byte[] getBytes() | 以字节数组的形式返回文件的内容 |
| String getContentType() | 返回文件的内容类型 |
| InputStream getInputStream() | 返回一个InputStream,从中读取文件的内容 |
| String getName() | 返回请求参数的名称 |
| String getOriginalFillename() | 返回客户端提交的原始文件名称 |
| long getSize() | 返回文件的大小,单位为字节 |
| boolean isEmpty() | 判断被上传文件是否为空 |
| void transferTo(File destination) | 将上传文件保存到目标目录下 |
commons-fileupload
commons-fileupload
1.4
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileExp {
private String description;
private CommonsMultipartFile multipartFile;
}
@Controller
@RequestMapping("/file")
public class FileUploadController {
@RequestMapping("/toUploadPage")
public String toUploadPage(){
return "uploadpage";
}
/**
* 把name=file控件的文件封装为一个CommonsMultipartFile对象
* 批量上传CommonsMultipartFile为数组即可
* @ModelAttribute 将对象作为model返回到前端
* */
@RequestMapping("/upload")
public String upload(@ModelAttribute("fileExp") FileExp fileExp, HttpSession session) throws IOException {
String filename = fileExp.getMultipartFile().getOriginalFilename(); //文件名
//若文件名为空则返回到上传页
if (StringUtils.isNullOrEmpty(filename)) {
return "redirect:/file/toUploadPage";
}
String uploadPath = session.getServletContext().getRealPath("/WEB-INF/upload");
File file1 = new File(uploadPath);
if (!file1.exists()) {
file1.mkdirs();
}
//文件输入流
InputStream is = fileExp.getMultipartFile().getInputStream();
//文件输出流
FileOutputStream fos = new FileOutputStream(new File(file1, filename));
byte[] bytes = new byte[1024*1024];
int read = 0;
if ((read = is.read(bytes))!=-1){
fos.write(bytes,0,read);
fos.flush();
}
fos.close();
is.close();
return "result";
}
//采用file.transferTo上传文件
@RequestMapping("/upload2")
public String upload2(@RequestParam("description") String description, @RequestParam("multipartFile") CommonsMultipartFile file, HttpSession session, Model model) throws IOException {
String filename = file.getOriginalFilename(); //文件名
//若文件名为空则返回到上传页
if (StringUtils.isNullOrEmpty(filename)) {
return "redirect:/file/toUploadPage";
}
//上传路径保存设置
String uploadPath = session.getServletContext().getRealPath("/WEB-INF/upload");
File file1 = new File(uploadPath);
if (!file1.exists()) {
file1.mkdirs();
}
file.transferTo(new File(file1,filename));
FileExp fileExp = new FileExp(description, file);
model.addAttribute("fileExp",fileExp);
return "result";
}
}
可以发现有两种方式:
- 一种通过流传输的方式将文件上传
- 另一种是CommonsMultipartFile对象的transferTo()方法,底层也是对流传输的封装。但用起来是方便不少。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
- application/x-www-form-urlencoded:这是默认的编码方式,它只处理表单域里的 value 属性值。类似get方式将name和value拼接到请求后面。
- multipart/form-data:该编码方式以二进制流的方式来处理表单数据,并将文件域指定文件的内容封装到请求参数里。
- text/plain:该编码方式只有当表单的 action 属性为“mailto:”URL 的形式时才使用,主要适用于直接通过表单发送邮件的方式。
另外注意:表单参数和实体类对应问题。
结果页面result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
结果页面
文件描述:${fileExp.description}
文件名:${fileExp.multipartFile.originalFilename}


//采用file.transferTo上传多文件
@RequestMapping("/upload3")
public String upload3(@ModelAttribute("filesExp") FilesExp filesExp, HttpSession session) throws IOException {
//上传路径保存设置
String uploadPath = session.getServletContext().getRealPath("/WEB-INF/upload");
File file1 = new File(uploadPath);
if (!file1.exists()) {
file1.mkdirs();
}
String filename = "";
//文件
List files = filesExp.getMultipartFile();
for (CommonsMultipartFile file: files) {
filename = file.getOriginalFilename();
if (StringUtils.isNullOrEmpty(filename)) {
return "result2";
}
file.transferTo(new File(file1,filename));
}
return "result2";
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
多文件上传
<%--
--%>
多文件上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
多文件上传结果显示
结果页面
文件名
文件描述
${filename.originalFilename}
${filesExp.description.get(status.index)}
