要在基于SpringMVC的Web应用程序中通过表单上传文件,那么MultipartResolver将是在服务器端处理文件上传的主要组件

 multipart/form-data编码方式支持基于表单的文件上传。

使用MultipartResolver进行文件上传的简单分析:

MultipartResolver的接口定义如下:

public interface MultipartResolver{     boolean isMultipart(HttpServletRequest request); 	MultipartHttpsServletRequest resolverMultipart(HttpServletRequest request)throws MultipartException; 	void cleanupMultipart(MultipartHttpServletRequest request);  }

MultipartResolver 位于 HandlerMapping 之前,请求一来就交由它来处理。当 Web 请求到达 DispatcherServlet 并等待处理的时候,
DispatcherServlet 首先会检查能否从自的 WebApplicationContext 中找到一个名称为 multipartResolver(由 DispatcherServlet 的
常量 MULTIPART_RESOLVER_BEAN_NAME 所决定)的 MultipartResolver 实例。如果能够获得一个 MultipartResolver 的实例,DispatcherServlet 
将调用 MultipartResolver 的 isMultipart(request) 方法检查当前 Web 请求是否为 multipart类型。如果是,DispatcherServlet 将调用 MultipartResolver 的
resolveMultipart(request) 方法,对原始 request 进行装饰,并返回一个 MultipartHttpServletRequest 供后继处理流程使用(最初的 HttpServletRequest 被偷梁
换柱成了 MultipartHttpServletRequest),否则,直接返回最初的 HttpServletRequest

SpringMVC框架内为MultipartResolver提供了两个可用的实现类,即org.springframework.web.multipartcommons.CommonsMultipartResolver
和org.springframework.web.multipart.cos.CosMultipartResolver。前者使用CommonsFileUpload类库实现,后者则使用Oreilly Cos类库实现
我们选择使用CommonsFileUpload进行文件上传,需要在DispatcherServlet的WebApplicationContext中添加bean定义如下:

<bean id="multipartResolver" 		class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 		p:maxUploadSize="1000000"> <bean/>

CommonsMultipartResolver将负责分析当前multipart请求,然后将分析的结果附着到要返回的MultipartHttpservletRequest实例上。当后继处理

流程的controller处理web请求的时候,就可以使用特定的MultipartHttpsServletRequest进行上传文件的获取和处理。

但MultipartResolver返回MultipartHttpServlet给后继处理流程,并且后继处理流程中的组件也使用MultipartHttpServletRequest处理完相应的Web
请求,DispatcherServlet将保证调用MultipartResolver的CleanupMultipart()方法,释放处理文件上传过程中所占用的系统资源,这样,整个文件上传
的生命周期即告结束。

下面来介绍一下我实现的文件上传的例子


要实现文件上传,首先添加一个MultipartResolver的实例到DispatcherServlet的WebApplicationContext中。

<bean id="multipartResolver" 		class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 		p:maxUploadSize="1000000"> 	</bean>

为了使用SimpleFormController专门处理表单的提交,我们需要为数据绑定提供一个Command对象,定义如下:

public class FileUploadingCommand { 	private byte[] fileToUpload; 	private String comment; 	public byte[] getFileToUpload() { 		return fileToUpload; 	} 	public void setFileToUpload(byte[] fileToUpload) { 		this.fileToUpload = fileToUpload; 	} 	public String getComment() { 		return comment; 	} 	public void setComment(String comment) { 		this.comment = comment; 	} 	@Override 	public String toString() { 		return new ToStringBuilder(this).append("fileToUpload",fileToUpload).append("comment",comment).toString(); 	} }

定义的最终的Controller实现类如下:

public class FileUploadFormController extends SimpleFormController{     @Override 	protected void doSubmitAction(Object command) throws Exception { 		FileUploadingCommand commandBean=(FileUploadingCommand)command; 		byte[] fileContent=commandBean.getFileToUpload(); 		String comment=commandBean.getComment(); 		FileUtils.writeByteArrayToFile(new File("zhsi"), fileContent); 	} 	 	@Override 	protected void initBinder(HttpServletRequest request, 			ServletRequestDataBinder binder) throws Exception { 		super.initBinder(request, binder); 		binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor()); 		 	} }

为了在数据绑定过程数据能够成功转型,我们需要为DataBinder添加相应的自定义PropertyEditor实现,覆写SimpleFormController的initBinder()

方法可以达到目的。

下面是SpringMVC.xml配置文件:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 		<property name="mappings"> 			<props> 				<prop key="login.do">login</prop> 			</props> 		</property> 	</bean> 	<bean name="login" class="com.web.springMVC.controller.FileUploadFormController">  		<property name="commandName"> 			<value>command</value> 		</property> 		<!-- 这里直接实现了将请求参数绑定到对象上 --> 		<property name="commandClass"> 		<value>com.web.springMVC.model.FileUploadingCommand</value> 		</property> 		<property name="successView" value="success"></property>  	<bean/> 	<bean id="multipartResolver" 		class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 		p:maxUploadSize="1000000"> 	</bean> 	<bean id="viewResolver" 		class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 		<property name="prefix" value="/WEB-INF/jsp/" />  <!-- 默认放在WebRoot下 --> 		<property name="suffix" value=".jsp" />  	</bean>

页面login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" 	pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 	<form action="login.do" method="post" enctype="multipart/form-data"> 		选择上传文件<input name="fileToUpload" type="file"/><br/> 		文件说明<textarea name="comment"></textarea> 		<input name="submit" type="submit" value="提交"/> 	</form> </body> </html>

页面success.jsp

<body> 	<table> 		<tbody> 			<tr> 				<td>User Info:</td> 			</tr> 			<tr> 				<td><c:out value="${command.comment}"></c:out></td> 			</tr> 		</tbody> 	</table> </body>

上述便可以实现简单的文件上传了