一、添加 jar 文件:commons-fileupload-1.3.1.jar 和其依赖的 commons-io-2.2.jar。
二、配置 web.xml
<!-- ①配置 SpringMVC DispatcherServlet --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置 DispatcherServlet 的一个初始化参数: 配置 SpringMVC 配置文件的位置和名称 --> <!-- 实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件, 而使用默认的. 默认的配置文件为: /WEB-INF/<servlet-name>-servlet.xml --> <!-- <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.d</url-pattern> </servlet-mapping>
<!-- ②配置 SpringMVC 字符过滤器 CharacterEncodingFilter --> <filter> <filter-name>SpringCharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>SpringCharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
三、配置 SpringMVC 的配置文件dispatcher-servlet.xml
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <!-- 指定所上传文件的总大小不能超过200KB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 --> <property name="maxUploadSize" value="200000"/> </bean> <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException --> <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 --> <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 --> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop> </props> </property> </bean>
四、编写处理器中的目标方法
@Controller
public class UserHandler {
@RequestMapping(value = "/saveOrUpdateUser.d")
// user 入参用于接收页面上非上传文件属性值,MultipartFile 参数用于接收 上传的文件 public void addUser(HttpServletResponse response, HttpServletRequest request, UserBean user, MultipartFile photo, BindingResult result) {
if(result.getErrorCount() > 0){//打印绑定异常信息 for (FieldError error : result.getFieldErrors()) { System.out.println(error.getField() + " $$ " + error.getDefaultMessage()); } } if(photo.isEmpty()){ System.out.println("用户未上传头像"); }else{ String baseDir = "/uplod/user/"; System.out.println("文件长度: " + photo.getSize()); System.out.println("文件类型: " + photo.getContentType()); System.out.println("文件名称: " + photo.getName()); System.out.println("文件原名: " + photo.getOriginalFilename()); System.out.println("========================================"); //如果用的是Tomcat服务器,则文件会上传到\%TOMCAT_HOME%\webapps\YourWebProject\upload\user 文件夹中 String realPath = request.getSession().getServletContext().getRealPath(baseDir); //这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉,我是看它的源码才知道的 try { FileUtils.copyInputStreamToFile(photo.getInputStream(), new File(realPath, photo.getOriginalFilename()));//写到本地目录 user.setPhoto_path(baseDir + photo.getOriginalFilename()); } catch (IOException e) { e.printStackTrace(); System.out.println("用户照片上传失败"); }
//记录到数据库等其它操作... }
}
}
五、其它注意点
1、页面上 file 控件的 name 属性值一定不能和 JavaBean 中 存放文件路径的成员变量名一样,否则上传失败。
例如页面上 name = photo,JavaBean 声明 photoPath 成员变量存放文件路径。
2、如果只是上传一个文件,目录方法中使用 MultipartFile 类型参数接收上传文件,属性名称必须和页面上 name 属性值一致,且无需显式指定@RequestParam注解。
3、如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解,并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是photo,否则参数里的photo无法获取到所有上传的文件。
4、随机文件名常用的三种方式:文件上传功能(增强:防止文件重名覆盖)
fileName = UUID.randomUUID().toString() + extName;
fileName = System.nanoTime() + extName;
fileName = System.currentTimeMillis() + extName;