SpringMVC学习笔记–文件上传与MultipartResolver

2023年2月20日07:55:29
要在基于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>

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

  • 作者:cwzhsi
  • 原文链接:https://blog.csdn.net/cwzhsi/article/details/41907651
    更新时间:2023年2月20日07:55:29 ,共 4696 字。