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>
上述便可以实现简单的文件上传了
热门文章
- 「1月16日」最高速度20.6M/S,2025年SSR/Clash/V2ray/Shadowrocket每天更新免费订阅地址分享
- 重庆宠物领养中心电话号码是多少啊(重庆最大免费宠物领养平台)
- netty系列之:netty中的核心编码器base64
- 「1月25日」最高速度18.7M/S,2025年Clash/Shadowrocket/V2ray/SSR每天更新免费订阅地址分享
- 猫粮品牌推荐(猫粮品牌推荐大全)
- 「12月11日」最高速度18.3M/S,2024年V2ray/Shadowrocket/SSR/Clash每天更新免费节点订阅链接
- Java基础|Java8接口新特性
- windows 平台下编译openssl 最新版本-3.0.5
- 狗领养协议有没有法律效应(领养狗协议书范本)
- echarts根据数据动态生成不同条数的折线图