SpringMVC 的文件上传

springmvc 为文件上传提供了两种形式,一种是基于Commons FilesUpload,另外一种是基于Servlet 3.0对 multipart 请求解析的支持。springmv下org.springframework.web.multipart包提供了对文件上传的支持。默认情况下,spring是不提供对文件上传的支持的,开发者需要在应用上下文中加入MultipartResolver的声明才可使用。

这篇文章主要是针对Commons FilesUpload这种形式。

    测试的Demo使用Maven构建构建,需要注意的是,使用 commons filesUpload 这种形式的,需要加入commons-fileupload以及commons-io这两个依赖包。

    项目目录如下:

SpringMVC 的文件上传_第1张图片

上传文件保存在upload/temp文件夹下,spring的配置文件放在了conf/spring 文件夹下

     项目的pom.xml如下


  4.0.0
  com.lee
  spring-mvc-demo
  war
  0.0.1-SNAPSHOT
  spring-mvc-demo Maven Webapp
  http://maven.apache.org
  
  
  	utf-8
  
 
  
	
		org.springframework
		spring-web
		3.2.0.RELEASE
	
	
		org.springframework
		spring-webmvc
		3.2.0.RELEASE
	
    
		javax.servlet
		javax.servlet-api
		3.0.1
		provided
	
	
	
		commons-fileupload
		commons-fileupload
		1.2
	
	
		commons-io
		commons-io
		1.3
	
	
      junit
      junit
      3.8.1
      test
    
  
 
  
    spring-mvc-demo
    
    	
		  org.eclipse.jetty
		  jetty-maven-plugin
		  9.2.11.v20150529
		
    	
    		 org.apache.maven.plugins
	         maven-compiler-plugin
	         3.3
    		 
    			1.7
    			1.7
    			utf-8
    		 
    	 
    
  
  
注:使用jetty,所以需要加入javax.servlet-api的依赖

有关于web.xml文件配置就不再赘述了。

在dispatcher-servlet.xml,需要加入MultipartResolver,如下

 


有个问题必须注意,在上面的配置中,bean的id必须是multipartResolver,否则会在做上传的时候抛出异常。

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: 

is a MultipartResolver configured?。

这是为什么呢?原因很简单。

打开DispatcherServlet这个类的源码,查看关于MultipartResolver初始化方法initMultipartResolver(ApplicationContext context) 的声明,源码如下


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 + "]");
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Default is no multipart resolver.
			this.multipartResolver = null;
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +
						"': no multipart request handling provided");
			}
		}
	}

我们发现,DispatcherServlet在做MultipartResolver初始化时,是通过getBean(String name, Class requiredType)方法来获取对应的MultiartResolver,而在做初始化时调用这个方出入的参数 name 是在DispatcherServlet定义的一个静态变量,如下

public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";


所以,在 dispatcher-servlet.xml 声明MultipartResolver时,bean的id或是name 必须是multipartResolver,否者的话它就找不到对应的MultipartResolver,最终导致抛出上面的异常
到此为止,项目配置完毕。
     文件上传页面如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




文件上传




单文件上传

多文件上传

需要注意的是,form的enctype 必须设置为multipart/form-data。
然后就是编写对应的Controller,代码如下,

package com.lee.springmvc.controller;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/** 
 * 
 * 文件上传controller
 * @author  Lee E-mail: [email protected]
 * @date 创建时间:2015年11月29日 上午2:21:52 
 * @version 1.0  
 */

@Controller
public class FileController {
	
	/**
	 * 文件上传页面跳转
	 */
	@RequestMapping(value="/upload")
	public String uploadForward(){
		return "upload";
	}
	
	/**
	 *   单文件上传
	*  @param singleFile 上传的单个文件
	*  @param request
	 */
	@RequestMapping(value = "/upload/singleUpload", method=RequestMethod.POST)
	public String singleUpload(@RequestParam("singleFile")  MultipartFile singleFile, HttpServletRequest request) throws IOException{
		String savePath = request.getSession().getServletContext().getRealPath("upload/temp");
		if(singleFile != null && !singleFile.isEmpty()){
			String fileName = singleFile.getOriginalFilename();
			//采用UUID生成随机文件名
			fileName = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
			File targetFile = new File(savePath, fileName);
			if(!targetFile.exists()){
				targetFile.mkdir();
			}
			singleFile.transferTo(targetFile);
		}
		return "success";
	}
	
	/**
	 *  多文件上传
	*  @param multiFiles MultipartFile 数组,对应上传的多个文件
	 */
	@RequestMapping(value = "/upload/multiUpload", method=RequestMethod.POST)
	public String multiUpload(@RequestParam("multiFiles")  MultipartFile[] multiFiles, HttpServletRequest request) throws IOException{
		String savePath = request.getSession().getServletContext().getRealPath("upload/temp");
		if(multiFiles != null && multiFiles.length > 0){
			for(MultipartFile file: multiFiles){
				if(file != null && !file.isEmpty()){
					String fileName = file.getOriginalFilename();
					//采用UUID生成随机文件名
					fileName = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
					File targetFile = new File(savePath, fileName);
					if(!targetFile.exists()){
						targetFile.mkdir();
					}
					file.transferTo(targetFile);
				}
			}
		}
		return "success";
	}
}
注:为了简便,并未做异常处理,实际项目中须有对应的异常处理。

到此为止,代码部分也书写完毕。
测试
多文件上传:
SpringMVC 的文件上传_第2张图片
点击提交按钮,上传成功,跳转到success页面,此时,在upload/temp文件夹下就可以找到上传的图片了
SpringMVC 的文件上传_第3张图片

到此为止,关于springmvc的文件上传就完毕了。有不足的地方请多指教。


你可能感兴趣的:(SpringMVC)