SpringMVC提供了文件上传的功能,接下来我们就简单了解一下SpringMVC文件上传的开发及大致过程。

首先需要在springMVC的配置文件中配置文件上传解析器

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

springMVC的文件上传需要commons-fileupload 包的支持,需要引入。

<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.3.2</version>
		</dependency>

文件上传的jsp表单页面页面,文件名称为file:

<form id='fForm' class="form-actions form-horizontal" action="/file/upload.action"
		      encType="multipart/form-data" target="uploadf" method="post">
				 <div class="control-group">
					<label class="control-label">上传文件:</label>
					<div class="controls">
						<input type="file"  name="file" style="width:550">

					</div>
				</div>
				 <div class="control-group">
					<div class="controls">
					<button type="button" id="subbut" class="btn">submit</button>
					</div>
				</div>
		</form>

文件上传的后台处理页面

@Controller
@RequestMapping("/file")
public class FileUpload {

	@RequestMapping("/upload")
	@ResponseBody
	public String upload(@RequestParam(value = "file", required = false)MultipartFile... files ){

		for (MultipartFile f : files) {
			if (f.getSize() > 0) {
				File targetFile = new File("1.jpg");
				try {
					f.transferTo(targetFile);
				} catch (IllegalStateException | IOException e) {
					e.printStackTrace();
				}
			}
		}

		return null;
	}

	@RequestMapping("/uploads")
	public String uploads(){
		return "fileupload";
	}
}

这样就可以在jsp页面中提交一个图片,后台将图片保存到工程目录下,页面如下:

接下来我们了解一下文件上传到达处理的Controller时做的预处理

在请求到达DispatcherServelet时,对文件上传处理的操作是在doDispatch方法中,用于判断这个请求是否是文件上传操作,具体的文件上传相关的操作都在这个方法中实现了。

processedRequest = checkMultipart(request);
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
		//首先判断请求是否是文件上传
		if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
			if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
				logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
						"this typically results from an additional MultipartFilter in web.xml");
			}
			else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {
				logger.debug("Multipart resolution failed for current request before - " +
						"skipping re-resolution for undisturbed error rendering");
			}
			else {
				return this.multipartResolver.resolveMultipart(request);
			}
		}
		//如果不是文件上传则直接返回请求
		// If not returned before: return original request.
		return request;
	}

this.multipartResolver.isMultipart(request)这个方法操作用来判断请求是否是文件上传操作,具体实现是在我们配置的multipartResolver中

@Override
	public boolean isMultipart(HttpServletRequest request) {
		return (request != null && ServletFileUpload.isMultipartContent(request));
	}

ServletFileUpload.isMultipart方法判断请求是否是文件上传的实现是在commons-fileupload包中了,这就是我们为什么需要引入commons-fileupload的原因

当我们已经判断请求是文件上传的请求时,接下来的操作是在this.multipartResolver.resolveMultipart(request);中了。

CommonsMultipartResolver类中的resolveMultipart方法

@Override
	public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
		Assert.notNull(request, "Request must not be null");
		//this.resolveLazily默认值是false
		if (this.resolveLazily) {
			return new DefaultMultipartHttpServletRequest(request) {
				@Override
				protected void initializeMultipart() {
					MultipartParsingResult parsingResult = parseRequest(request);
					setMultipartFiles(parsingResult.getMultipartFiles());
					setMultipartParameters(parsingResult.getMultipartParameters());
					setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
				}
			};
		}
		else {
			MultipartParsingResult parsingResult = parseRequest(request);
			return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
					parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
		}
	}

具体的解析过程我们就不分析了,最终结果是生成一个DefaultMultipartHttpServletRequest,其主要的实现就是将我们在前端页面上传的文件file,生成MultipartFile对象,这就是为什么在Controller中,我们file参数的类型是MultipartFile,如下,这样我们就可以通过MultipartFile来进行编程来实现文件的一系列操作了。

public String upload(@RequestParam(value = "file", required = false)MultipartFile... files ){

		for (MultipartFile f : files) {
			if (f.getSize() > 0) {
				File targetFile = new File("1.jpg");
				try {
					f.transferTo(targetFile);
				} catch (IllegalStateException | IOException e) {
					e.printStackTrace();
				}
			}
		}

		return null;
	}

SpringMVC源码分析--文件上传的更多相关文章

  1. THINKPHP源码学习--------文件上传类

    TP图片上传类的理解 在做自己项目上传图片的时候一直都有用到TP的上传图片类,所以要进入源码探索一下. 文件目录:./THinkPHP/Library/Think/Upload.class.php n ...

  2. 源码解读-文件上传angularFileUpload1

    angular-file-upload 1.文件上传模块的引入就不赘述,简单准备 2.初始化组件并绑定change事件 3.监听用户选择文件FileItem(change事件),push进文件数组qu ...

  3. PHP 大文件上传,支持断点续传,求具体方案、源码或者文件上传插件

    文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...

  4. springMVC源码分析--DispatcherServlet请求获取及处理

    在之前的博客springMVC源码分析--容器初始化(二)DispatcherServlet中我们介绍过DispatcherServlet,是在容器初始化过程中出现的,我们之前也说过Dispatche ...

  5. SpringMVC源码分析--容器初始化(五)DispatcherServlet

    上一篇博客SpringMVC源码分析--容器初始化(四)FrameworkServlet我们已经了解到了SpringMVC容器的初始化,SpringMVC对容器初始化后会进行一系列的其他属性的初始化操 ...

  6. SpringMVC源码分析(3)DispatcherServlet的请求处理流程

    <springmvc源码分析(2)dispatcherservlet的初始化>初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的 ...

  7. 框架-springmvc源码分析(一)

    框架-springmvc源码分析(一) 参考: http://www.cnblogs.com/heavenyes/p/3905844.html#a1 https://www.cnblogs.com/B ...

  8. [心得体会]SpringMVC源码分析

    1. SpringMVC (1) springmvc 是什么? 前端控制器, 主要控制前端请求分配请求任务到service层获取数据后反馈到springmvc的view层进行包装返回给tomcat, ...

  9. springMVC源码分析--国际化实现Session和Cookie(二)

    上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...

随机推荐

  1. springaop——AspectJ不可不知的细节

    springaop简介 springaop是spring对AOP技术的具体实现,它是spring框架的核心技术.springaop底层使用JDK动态代理或CGLIB动态代理技术实现. 应用场景: 在多 ...

  2. 智能合约开发solidity编程语言开发一个以太坊应用区块链投票实例

    智能合约开发用solidity编程语言部署在以太坊这个区块链平台,本文提供一个官方实战示例快速入门,用例子深入浅出智能合约开发,体会以太坊构建去中心化可信交易技术魅力.智能合约其实是"执行合 ...

  3. jdk 动态代理源码分析

    闲来无事,撸撸源码 使用方法 直接看代码吧.. package com.test.demo.proxy; import java.lang.reflect.InvocationHandler; imp ...

  4. Diango + uwsgi + nginx 项目部署(可外网访问)

    自己通过nginx uwsgi 部署django项目,查询了很多资料,遇到了很多问题,最终完成了部署,趁着心情愉悦,写个随笔,为曾像我一样苦寻解决方案的小伙伴们提供些思路. 安装Nginx: #安装n ...

  5. [BZOJ 3332]旧试题

    Description 圣诞节将至.一年一度的难题又摆在wyx面前——如何给妹纸送礼物. wyx的后宫有n人,这n人之间有着复杂的关系网,相互认识的人有m对.wyx想要量化后宫之间的亲密度,于是准备给 ...

  6. [HNOI2007]分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  7. 空间漫游(SAC大佬的测试)

    题目描述由于球哥和巨佬嘉诚交了很多保护费,我们有钱进行一次 d 维空间漫游.d 维空间中有 d 个正交坐标轴,可以用这些坐标轴来描述你在空间中的位置和移动的方向.例如,d = 1 时,空间是一个数轴, ...

  8. [JLOI2015]管道连接

    题目描述 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰.该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情报站 ui 和 v ...

  9. 删数方案数(regex)

    [题目描述] 给出一个正整数序列 a,长度为 n,cyb 不喜欢完美,他要删掉一些数(也可以不删,即删掉0个),但是他不会乱删,他希望删去以后,能将 a 分成 2 个集合,使得两个非空集合的数的和相同 ...

  10. DP测试总结

    T1:三取方格数 题目描述 设有N*N的方格图,我们将其中的某些方格填入正整数,而其他的方格中放入0.某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角.在走过的路上,他取走了方格中的数. ...