最近博主遇到一个需求在SpringMVC下实现文件上传,为此我研究了下 单文件 和 多文件 的上传。博主不敢藏私,特地与大家分享一下:
其中参考了几位大神的Blog:
1.多文件上传的几种实现方式与效率比较
http://blog.csdn.net/a1314517love/article/details/24183273
2.单文件上传的例子1
http://www.jb51.net/article/66340.htm
3.单文件上传的例子2
http://blog.csdn.net/cheung1021/article/details/7084673
如果对文件上传一点不懂的同学还可以参考以上博客:
1.首先需要引入额外的jar包
下载相关jar包。需要引入的jar出了springMVC的jar包外,还需要引入com.springsource.org.apache.commons.fileupload-1.2.0.jar和com.springsource.org.apache.commons.io-1.4.0.jar。所有的jar包可以通过“点击这里”进行下载。(jar路径博主复制别人的自己没测过,大家可以网上找下)
2.配置相应的SpringMvc的配置文件
重要的代码:
<!-- Enable file upload functionality -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760000"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
3.文件上传的部分
(1)单文件上传:
1)页面部分
<c:if test="${role == 'sys' }">
<div>
<form method="post" action="<%=request.getContextPath()%>/notice/upload.do" enctype="multipart/form-data" >
<input type="file" name="upLoadFile" value="选择上传的文件" />
<!-- Html5 多文件上传 multiple="multiple" -->
<input type="submit" value="上传单个文件测试"/>
</form>
</div>
</c:if>
2)Controller层
//测试文件上传
@RequestMapping("/upload")
public String upload(@RequestParam(value="upLoadFile", required = false) MultipartFile file, HttpServletRequest request, HttpSession session) {
String path = request.getSession().getServletContext().getRealPath("/upload/excel"); //文件在服务器上存储的位置
String originFileName = file.getOriginalFilename(); //获取原始文件的名字
System.out.println(originFileName); //上传文件的名字
String type = originFileName.substring(originFileName.lastIndexOf(".")+1); //获取文件的类型,以最后一个"."标识的文件类型作为标准
System.out.println(type);
String fileName = System.currentTimeMillis() + "." + type; //设置新文件的名字
File targetFile = new File(path, fileName); //在指定路径创建一个文件
try {
file.transferTo(targetFile); //将文件保存到服务器上指定的路径上
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/notice/queryNotice"; //重定向到一个controller
// return "redirect:yannan/notice/noticeList"; //重定向到一个页面
}
(2)多文件上传 (这里用到了HTML5 中 input type为file 后的 multiple属性)
1)页面部分
<c:if test="${role == 'sys' }">
<div>
<form method="post" action="<%=request.getContextPath()%>/notice/uploadMultFiles.do" enctype="multipart/form-data">
<input type="file" name="upLoadMultFiles" value="选择上传的文件" multiple="multiple" />
<!-- Html5 多文件上传 multiple="multiple" -->
<input type="submit" value="上传多个文件测试"/>
</form>
</div>
</c:if>
2)Controller层
//测试文件上传
@RequestMapping("/uploadMultFiles")
public String uploadMultFile(@RequestParam(value="upLoadMultFiles", required = false) CommonsMultipartFile[] files, HttpServletRequest request, HttpSession session) {
System.out.println(files.length);
for(int i=0; i<files.length; i++){
//记录上传过程起始时的时间,用来计算上传时间
int pre = (int) System.currentTimeMillis();
//取得当前上传文件的文件名称
String originFileName = files[i].getOriginalFilename(); //获取原始文件的名字
System.out.println(originFileName); //上传文件的名字
String type = originFileName.substring(originFileName.lastIndexOf(".")+1); //获取文件的类型,以最后一个"."标识的文件类型作为标准
System.out.println(type);
//定义上传路径
String path = request.getSession().getServletContext().getRealPath("/upload/excel"); //文件在服务器上存储的位置
String fileName = System.currentTimeMillis() + "." + type; //设置新文件的名字
File targetFile = new File(path, fileName); //在指定路径创建一个文件
try {
files[i].transferTo(targetFile); //将文件保存到服务器上指定的路径上
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//记录上传该文件后的时间
int finaltime = (int) System.currentTimeMillis();
System.out.println(finaltime - pre);
}
return "redirect:/notice/queryNotice"; //重定向到一个controller
// return "redirect:yannan/notice/noticeList"; //重定向到一个页面
}
测试结果:
txt * 1 通过单文件上传
doc * 2 通过多文件上传
额外的延伸:
到这里估计大家已经能实现自己想要的功能了,但是我想一定还会有人对 CommonsMultipartFile 和 MultipartFile 两个类的区别感到好奇。
恩,这里博主去找了下这两个类的介绍:
按照文档来看:CommonsMultipartFile 实现了 MultipartFile 接口,应该是一种多态性质的应用。(博主推测的,望各位大神看过了给予指点)
附API文档:
CommonsMultipartFile
MultipartFile
重点函数
transferTo 如果文件存在,则会先删除。。。
void transferTo(File dest) throws IOException, IllegalStateException
-
Transfer the received file to the given destination file.
This may either move the file in the filesystem, copy the file in the filesystem, or save memory-held contents to the destination file.If the destination file already exists, it will be deleted first.
If the file has been moved in the filesystem, this operation cannot be invoked again. Therefore, call this method just once to be able to work with any storage mechanism.
-
-
Parameters:
-
dest
- the destination file
Throws:
-
IOException
- in case of reading or writing errors -
IllegalStateException
- if the file has already been moved in the filesystem and is not available anymore for another transfer
-