修炼SpringMVC-核心技能-文件上传
在开发Web应用程序中,关于文件的上传操作是十分常见的,本节将了解下怎么利用SpringMVC进行文件上传。
一、关于文件上传的一些配置
1.导入上传的相关jar包
在SpringMVC中实现文件处上传需要导入以下两个Jar包(版本可能有所不同)。
com.springsource.org.apache.commons.fileupload-1.2.0.jar com.springsource.org.apache.commons.io-1.4.0.jar
2.在配置文件中配置Multipart处理器
要想实现文件上传,文件上传处理器是必不可少的如下:
<!--注册Multipart解析器 id是固定的 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 文件上传字符集限制(文件名) --> <property name="defaultEncoding" value="utf-8"/> <!-- 限制文件上传大小 ,单位:字节B--> <property name="maxUploadSize" value="1048576"/> </bean>
关于文件处理器需要注意的是id属性的值是固定的,必须为multipartResolver。这是因为是否进行文件上传,是在DispatcherServlet执行器中进行判断的,而且在加载时是固定的名称为multipartResolver的Bean。
//常量定义 public class DispatcherServlet extends FrameworkServlet { /** Well-known name for the MultipartResolver object in the bean factory for this namespace. */ public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; } //初始化MultipartResolver private void initMultipartResolver(ApplicationContext context) { try { this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using MultipartResolver [" + this.multipartResolver + "]"); } } }
3.注册注解驱动
<!-- 注册注解驱动--> <mvc:annotation-driven/>
注册注解驱动,这是因为用于接收文件上传表单参数的处理器MultipartFile接口,其实现类CommonsMultipartFile在进行注解驱动注册是被创建,并作为实参传递给处理器方法的形参MultipartFile。
二、处理器的编写
1.单文件上传处理
/** * 单文件上传 * @param uploadFile 与页面表单name一致 * @param session * @return * @throws Exception */ @RequestMapping("/upload.do") public ModelAndView doUpLoad(MultipartFile uploadFile, HttpSession session) throws Exception{ //判断是否有文件上传 if(!uploadFile.isEmpty()){ //获取项目中保存文件的【完整路径】的位置 String realPath = session.getServletContext().getRealPath("/file"); //获取上传文件的原文件名 String uploadFileName = uploadFile.getOriginalFilename(); System.out.println("realPath="+realPath+",uploadFileName="+uploadFileName); File file = new File(realPath,uploadFileName); //保存上传文件 uploadFile.transferTo(file); } return new ModelAndView("/index.jsp"); }
2.多文件上传处理
/** * 多文件上传 * @param uploadFile 与页面表单name一致 * @param session * @return * @throws Exception */ @RequestMapping("/uploads.do") public ModelAndView doUpLoads(@RequestParam MultipartFile[] uploadFiles, HttpSession session) throws Exception{ for (int i = 0; i < uploadFiles.length; i++) { //判断是否有文件上传 if(!uploadFiles[i].isEmpty()){ //获取项目中保存文件的【完整路径】的位置 String realPath = session.getServletContext().getRealPath("/file"); //获取上传文件的原文件名 String uploadFileName = uploadFiles[i].getOriginalFilename(); System.out.println("realPath="+realPath+",uploadFileName="+uploadFileName); File file = new File(realPath,uploadFileName); //保存上传文件 uploadFiles[i].transferTo(file); } } return new ModelAndView("/index.jsp"); }
3.分析
用于接收上传文件信息的形参类型是MultipartFile类型。我们看到在在处理多文件上传时,定义成数组即可MultipartFile[]。
那为什么处理多文件上传时需要@RequestParam修饰呢。这是因为在默认情况下,框架只会将上传文件一个一个的封装处理,而多文件处理是一个数组类型。加上@RequestParam表示表单传来的参数与处理器方法接收的参数名称与类型相同,需要框架调用相应的转换器将请求参数转换为方法中的参数类型。
在上传时,无论是单文件还是多文件上传,即使没有选择任何文件。
MultipartFile和MultipartFile[]也不会为null,而是一个empty的File,一个上传文件对应一个File(非null)。
4.jsp页面
<form action="upload.do" method="post" enctype="multipart/form-data"> 文件:<input type="file" name="uploadFile" /><br/> <input type="submit" value="提交"> </form> <br/> <form action="uploads.do" method="post" enctype="multipart/form-data"> 文件:<input type="file" name="uploadFiles" /><br/> 文件:<input type="file" name="uploadFiles" /><br/> <input type="submit" value="提交"> </form>