本篇概览
-
本章我们来一起阅读和分析 SpringMVC 的部分源码,看看收到 POST 请求中的二进制文件后,SpingMVC 框架是如何处理的;
-
使用了 SpringMVC 框架的 web 应用中,接收上传文件时,一般分以下三步完成:
-
在 spring 配置文件中配置一个 bean:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="10485760000" />
<property name="maxInMemorySize" value="40960" />
</bean>
pom.xml 中添加 apache 的 commons-fileupload 库的依赖:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
-
开发业务 Controller 的响应方法,以下代码是将 POST 的文件存储到应用所在的电脑上:
RequestMapping(value="/upload",method= RequestMethod.POST)
public void upload(HttpServletRequest request,
HttpServletResponse response,
@RequestParam("comment") String comment,
@RequestParam("file") MultipartFile file) throws Exception {
logger.info("start upload, comment [{}]", comment);
if(null==file || file.isEmpty()){
logger.error("file item is empty!");
responseAndClose(response, "文件数据为空");
return;
}
//上传文件路径
String savePath = request.getServletContext().getRealPath("/WEB-INF/upload");
//上传文件名
String fileName = file.getOriginalFilename();
logger.info("base save path [{}], original file name [{}]", savePath, fileName);
//得到文件保存的名称
fileName = mkFileName(fileName);
//得到文件保存的路径
String savePathStr = mkFilePath(savePath, fileName);
logger.info("real save path [{}], real file name [{}]", savePathStr, fileName);
File filepath = new File(savePathStr, fileName);
//确保路径存在
if(!filepath.getParentFile().exists()){
logger.info("real save path is not exists, create now");
filepath.getParentFile().mkdirs();
}
String fullSavePath = savePathStr + File.separator + fileName;
//存本地
file.transferTo(new File(fullSavePath));
logger.info("save file success [{}]", fullSavePath);
responseAndClose(response, "Spring MVC环境下,上传文件成功");
}
-
如上所示,方法入参中的 MultipartFile 就是 POST 的文件对应的对象,调用 file.transferTo 方法即可将上传的文件创建到业务所需的位置;
三个疑问
-
虽然业务代码简单,以上几步即可完成对上传文件的接收和处理,但是有几个疑问想要弄清楚:
-
为什么要配置名为 multipartResolver 的 bean;
-
为什么要依赖 apache 的 commons-fileupload 库;
-
从客户端的 POST 到 Controll