http://blog.csdn.net/yerenyuan_pku/article/details/72511975

这一篇博文主要来总结下SpringMVC中实现文件上传的步骤。但这里我只讲单个文件的上传。

环境准备

SpringMVC上传文件的功能需要两个jar包的支持,如下: 
 
工程中肯定要导入以上两个jar包,主要是CommonsMultipartResolver解析器依赖commons-fileupload和commons-io这两个jar包。

单个文件的上传

前台页面

我们要改造editItem.jsp页面,主要是在form表单中添加商品图片一栏,效果我截图如下: 

注意一点的是form表单中别忘了写enctype="multipart/form-data"属性。

对多部件类型multipart解析

意思就是说针对上面的enctype=”multipart/form-data”类型,SpringMVC需要对multipart类型的数据进行解析,在springmvc.xml中配置multipart类型解析器即可。如下:

<!-- 配置多媒体文件解析器 -->
<!-- 文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>

创建文件保存的虚拟目录

在上传文件之前,首先要创建一个虚拟目录来保存文件,这个虚拟目录会对应磁盘上的一个实际的目录,在实际开发中肯定会有一个服务器专门存储资源的,在这里我们就用本地磁盘来保存文件,然后映射一个虚拟目录,用来在程序中指定获取文件的路径(其实上面前台页面editItem.jsp中,那个src=”/pic/${item.pic}”中的/pic就是虚拟目录)。 
创建的方法有两种:一是在Eclipse中双击tomcat服务器,就会弹出下面的框框: 

选择Modules,然后点击【Add External Web Module…】,在弹出的对话框中进行如下操作,都在图里面了。 

设置好后,保存即可,这样上传的文件都会保存到Document base指定的目录中,相当于虚拟映射到Path指定的目录中,程序中获取这个文件,要从Path指定的虚拟目录中获取,即我上面的/pic。我可举一个例子,将一个图片(例如,0d318effd664668f555d43966b3294a6_b.jpg)拷贝到Document base指定的目录中,即F:\temp\images目录中,然后启动tomcat服务器,在浏览器地址栏中输入url访问地址——http://localhost:8080/pic/0d318effd664668f555d43966b3294a6_b.jpg即可访问到该图片。 
第二种方法就是在tomcat的配置文件中配置一下,其实刚刚在Eclipse中的操作已经自动写到这个配置文件中了,配置文件位置在tomcat目录/conf/server.xml中,看一下里面会多了一行: 

这就是刚刚我配置的,它自动写到这个文件中了,所以我们也可以直接自己在该配置文件中写,就不需要在Eclipse中配置了。

编写后台Controller方法

接下来就是重点了,前台传过来的文件,我们在ItemController类中需要进行处理,然后保存到磁盘中,同时也就映射到了我们配置的虚拟路径中了,那么如何接收呢?看下面的代码:

@RequestMapping(value="/updateitem",method={RequestMethod.POST,RequestMethod.GET})
public String updateItems(Items items, MultipartFile picture) throws Exception {
// 把图片保存到图片目录下
// 保存图片,这个图片有的时候文件名可能会重复,你保存多了会把原来的图片给覆盖掉,这就不太合适了。
// 所以为每个文件生成一个新的文件名
String picName = UUID.randomUUID().toString();
// 截取文件的扩展名(如.jpg)
String oriName = picture.getOriginalFilename();
String extName = oriName.substring(oriName.lastIndexOf("."));
// 保存文件
picture.transferTo(new File("F:\\temp\\images\\" + picName + extName)); // 把文件名保存到数据库
items.setPic(picName + extName);
itemService.updateItem(items);
return "forward:/item/itemEdit.action";
}

注意:考虑实际情况,保存图片时一般不只你一个人保存图片,那么这个图片有的时候文件名可能会重复,你保存多了会把原来的图片给覆盖掉,这就不太合适了,所以需要使用UUID算法为每个文件生成一个新的文件名。 
首先来看一下形参,主要有Items和MultipartFile类型的picture,我这里上传一张图片是ItemsCustom类的一个属性,所以有了这个形参,是为了写到该类中,SpringMVC文件上传的类是MultipartFile,参数名称picture必须和前台editItem.jsp页面的name属性一致才行。上传图片之后的效果类似于: 

并且图片的文件名也保存到了数据库表中,如下: 

最后总结一下,我上传文件的逻辑可能判断不严谨,如果说要更加严谨一点的话, 上传文件的逻辑就应是:首先判断有没有上传文件,如果上传了,那么对文件重新命名然后写到磁盘中。如果没有上传文件,那么我应该还是用原来的文件(图片)。读者如果有兴趣可以参考下面代码:

@RequestMapping(value="/updateitem",method={RequestMethod.POST,RequestMethod.GET})
public String updateItems(Items items, MultipartFile picture) throws Exception { // 处理上传的单个图片
String originalFileName = picture.getOriginalFilename();// 原始名称
// 上传图片
if (picture != null && originalFileName != null && originalFileName.length() > 0) {
// 存储图片的物理路径,实际中是要写到配置文件中的,不能在这写死
String pic_path = "F:\\temp\\images\\";
// 新的图片名称
String newFileName = UUID.randomUUID()
+ originalFileName.substring(originalFileName
.lastIndexOf("."));
File newFile = new File(pic_path + newFileName);//新图片
picture.transferTo(newFile);// 将内存中的数据写入磁盘
items.setPic(newFileName);// 将新图片名称写到itemsCustom中
} else {
//如果用户没有选择图片就上传了,还用原来的图片
Items temp = itemsService.findItemsById(items.getId());
items.setPic(temp.getPic());
} // 调用service更新商品信息,页面需要将商品信息传到此方法
itemService.updateItem(items);
return "forward:/item/itemEdit.action";
}

到这里,单个文件的上传我就已总结完了。

最新文章

  1. Rss 订阅:php动态生成xml格式的rss文件
  2. 解决Tomcat catalina.out 不断成长导致档案过大的问题
  3. xll调试方法
  4. C part 1 -- 指令篇
  5. django1.6.x(python3.3)使用pymysql连接mysql
  6. Forget Java to learn Javascript from 0.--Preface
  7. JSON--stringify() 和 parse() 方法
  8. Android程序崩溃异常处理框架
  9. make capslock+hjkl as arrows
  10. jquery-confirm使用方法
  11. 【php增删改查实例】第十六节 - 用户新增
  12. 如何用Baas快速在腾讯云上开发小程序-系列4:实现客户侧商品列表、商品详情页程序
  13. seo中的竞价排名是什么
  14. 增加临时表空间组Oracle11g单实例
  15. 【Python】CVE-2017-10271批量自查POC(Weblogic RCE)
  16. IOS多线程之序
  17. 全面支持Angular2的Web后台Bootstrap模板Sing App - Web &amp; Angular 2.0 Dashboard
  18. 数据结构(Data Structures)
  19. UIControl事件---iOS-Apple苹果官方文档翻译
  20. AngularJs使用过程中,在ng-repeat中使用track by

热门文章

  1. maven(二)创建一个maven的web项目中解决Cannot change version of project facet Dynamic web module to 2.5
  2. 【旧文章搬运】PE重定位表学习手记
  3. Spring AOP schema找不到报错 原
  4. View Controller Programming Guide for iOS---(五)---Resource Management in View Controllers
  5. python学习笔记5-自定义函数
  6. python学习笔记1-基础语法
  7. bzoj 4472: [Jsoi2015]salesman【树形dp+贪心】
  8. Luogu P1754球迷购票问题【dp/卡特兰数】By cellur925
  9. js和jquery给iframe src赋值的3种方法
  10. web.xml中classpath*:与classpath:的区别