spring mvc 提交表单实现文件上传服务器

来源:互联网 发布:类似photosynth的软件 编辑:程序博客网 时间:2024/06/05 17:39

一、准备好form表单,代码如下:

<form action="/App/upload/uploadfile?name='22.jpg'" method="post" target="id_iframe" enctype="multipart/form-data">  <p><input type="file" name="myfile" value="浏览文件"></p>  <p><input type="submit" value="上传"></p>  </form><iframe id="id_iframe" name="id_iframe" style="display:none"></iframe>
1. App是应用的根目录,upload/uploadfile是服务端映射路径。
2. form表单提交类型一定要加上enctype="multipart/form-data",这是提交媒体文件的声明。
3. form表单提交的target="id_iframe",是为后台处理完成后返回结果刷新name为id_iframe的iframe。这样就不会刷新当前页面。

二、后台controller接收请求,代码如下:

import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.annotation.Resource;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.commons.fileupload.servlet.ServletRequestContext;import org.apache.log4j.Logger;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@Controller@RequestMapping(value="/upload")public class UploadController {static Logger logger = Logger.getLogger(UploadController.class); @RequestMapping(value="/uploadfile",method = RequestMethod.POST)@ResponseBodypublic String uploadFile(HttpServletRequest request){try{boolean isMultipart = ServletFileUpload.isMultipartContent(request); logger.info("命中目标1:"+isMultipart);logger.info("文件名:"+request.getParameter("name"));if(isMultipart){  String fileName = request.getParameter("name");FileItemFactory factory = new DiskFileItemFactory();//ServletFileUpload对象的创建需要依赖FileItemFactory工厂将获得的上传文件FileItem对象保存至服务器硬盘,即DiskFileItem对象ServletFileUpload upload = new ServletFileUpload(factory);//设置允许上传的最大文件大小 4Mupload.setSizeMax(4*1024*1024);//解析http请求消息头List<FileItem> fileItems = upload.parseRequest(new ServletRequestContext(request));Iterator iter = fileItems.iterator();//要执行while内逻辑,需在bean文件中有相应配置,后面会有说明。while(iter.hasNext()){FileItem item = (FileItem)iter.next();if(item.isFormField()){System.out.println("处理表单内容");processFormField(item,fileName);}else{System.out.println("处理上传文件");processUploadFile(item,fileName);}}} return "upload file ok";}catch(Exception e){System.out.println("使用 fileupload 包时发生异常 ..."); e.printStackTrace();return "upload file error";}}public void processFormField(FileItem item, String fileName) {String name = item.getFieldName();String value = item.getString();logger.info("表单域名为:" + name + "值为:" + value);}public void processUploadFile(FileItem item, String fileName){String filename = null;//获得文件名,此文件名包含路径if(fileName!=null){filename = fileName;}else{filename = item.getName();}logger.info("文件名:"+filename);if(filename!=null){File file = new File(filename);logger.info("创建文件对象File:"+file);String path = "/home/weblogic/";//判断路径是否存在File dirFile = new File(path);if(!dirFile.exists()){dirFile.mkdirs();}File filetoserver = new File(path,file.getName());  try{item.write(filetoserver); }catch(Exception e){logger.info("文件上传服务器,写入异常");e.printStackTrace();}logger.info("文件:" + filetoserver.getName() + "上传成功");}else{logger.info("文件上传失败");}}}
在此,文件上传的实现,使用的是apache的ServletFileUpload,如果同时使用MultipartResolver 和ServletFileUpload,就会在iter.hasNext()返回false,然后整个循环就跳不出去了。整个问题产生的原因是Spring框架先调用了MultipartResolver 来处理http multi-part的请求。这里http multipart的请求已经消耗掉。后面又交给ServletFileUpload ,那么ServletFileUpload 就获取不到相应的multi-part请求。解决方法是加入multipartResolver来单独处理某些请求。
package com.util;import javax.servlet.http.HttpServletRequest;import org.springframework.web.multipart.commons.CommonsMultipartResolver;/** *  @author yawenchen *  解决:Spring MultipartResolver 或者 ServletFileUpload 冲突导致获取不到http数据/Multipart数据为空 */public class MyMultipartResolver extends CommonsMultipartResolver{    private String excludeUrls;         private String[] excludeUrlArray;            public String getExcludeUrls() {          return excludeUrls;      }      public void setExcludeUrls(String excludeUrls) {          this.excludeUrls = excludeUrls;          this.excludeUrlArray = excludeUrls.split(",");      }         /**      * 这里是处理Multipart http的方法。如果这个返回值为true,那么Multipart http body就会MyMultipartResolver 消耗掉.如果这里返回false      * 那么就会交给后面的自己写的处理函数处理例如刚才ServletFileUpload 所在的函数      * @see org.springframework.web.multipart.commons.CommonsMultipartResolver#isMultipart(javax.servlet.http.HttpServletRequest)      */      @Override      public boolean isMultipart(HttpServletRequest request) {          for (String url: excludeUrlArray) {          // 这里可以自己换判断          if (request.getRequestURI().contains(url)) {              return false;          }          }          return super.isMultipart(request);     }}

三、在web.xml中这样配置

<bean id="multipartResolver" class="com.util.MyMultipartResolver">  <property name="excludeUrls" value="uploadfile"/>  <!-- url中带有uploadfile的http请求就不会被multipartResolver先解析--><property name="defaultEncoding"><value>UTF-8</value></property><property name="maxUploadSize"><value>104857600</value><!-- 上传文件大小限制为31M,31*1024*1024 --></property><property name="maxInMemorySize"><value>4096</value></property></bean>





1 0
原创粉丝点击