码迷,mamicode.com
首页 > 编程语言 > 详细

SpringMVC文件上传的两种方式

时间:2014-12-06 16:47:06      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

  搞JavaWEB的应该或多或少都做过文件上传,之前也做过简单的上传,但是如下的需求也确实把我为难了一把:

        1、上传需要异步,

        2、需要把上传后文件的地址返回来,

        3、需要进度条显示上传进度.

  项目使用SpringMVC架构+easyUI,初步分析,进度条可以使用easyui自带的进度条,上传可以使用ajaxFileUpload或者ajaxForm。文件传上去,然后把路径带回来是没问题的,关键是上传进度怎么获取。最终,两种方式都实现啦。

首先,不管哪种方式,后台对文件处理都是必须的。文件处理:

bubuko.com,布布扣
 1 /**
 2 * 文件上传处理方法
 3 * @param fileType 上传文件的类型
 4 * @param file 上传的文件
 5  */
 6 @RequestMapping("file/uploadFile")
 7 public void uploadVideo(int fileType,MultipartFile file) {
 8     Map<String, Object> map = new HashMap<String,Object>();
 9     map.put("status", "error");
10     try {
11         if (file.getSize() > 500 * 1024 * 1024) {
12             map.put("status", "size_err");
13         }else if(file!=null){
14             String suffix=file.getOriginalFilename().toLowerCase();
15             suffix = suffix.substring(suffix.lastIndexOf("."));
16             String fileDir = "upload/";
17             switch (fileType) {
18             case 1:
19                 fileDir += "video/";//视频文件
20                 break;
21             case 2:
22                 fileDir += "picture/";//图片文件
23                 break;
24             default:
25                 break;
26             }
27             String fileName=fileDir+UUID.randomUUID()+suffix;
28             File newFile=newFile(Constant.WEB_ROOT_PATH+ fileName);
29             File dir = newFile.getParentFile();
30             if (!dir.isDirectory()) {
31                 dir.mkdirs();
32             }
33                         //自定义fileCopy方法
34             FileCopyUtils.copy(file.getBytes(),newFile);
35             map.put("data", Config.get().getDomain()+fileName);
36             session.setAttribute("read",100);//稍后进度条用到
37             map.put("status", "success");    
38             }
39         } catch (Exception e) {
40             e.printStackTrace();
41         } finally{
42             outJSON(map);
43         }
44     }
View Code

方式一 使用ajaxFileUpload:

1.重写CommonsMultipartResolver以监听文件上传进度:

bubuko.com,布布扣
 1 /**
 2  * 重写CommonsMultipartResolver以监听文件上传进度
 3  */
 4 public class PJCommonsMultipartResolver extends CommonsMultipartResolver {
 5     private HttpServletRequest request;
 6     protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
 7     ServletFileUpload upload=new ServletFileUpload(fileItemFactory);
 8     upload.setSizeMax(-1);
 9     if (request != null) {
10         HttpSession session = request.getSession();
11         PJProgressListener uploadProgressListener=new PJProgressListener(session);
12         upload.setProgressListener(uploadProgressListener);
13     }
14     return upload;
15 }
16 
17     public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
18         this.request = request;// 获取到request,要用到session
19         return super.resolveMultipart(request);
20     }
21     @SuppressWarnings("unchecked")
22     @Override
23     public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
24         HttpSession session = request.getSession();
25         String encoding = "utf-8";
26         FileUpload fileUpload = prepareFileUpload(encoding);
27         PJProgressListener uploadProgressListener = new PJProgressListener(session);
28         fileUpload.setProgressListener(uploadProgressListener);
29         try {
30             @SuppressWarnings("rawtypes")
31             List fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
32             return parseFileItems(fileItems, encoding);
33         } catch (FileUploadBase.SizeLimitExceededException ex) {
34             throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
35         } catch (FileUploadException ex) {
36             throw new MultipartException("Could not parse multipart servlet request", ex);
37         }
38     }
View Code

2.实现进度监听接口:

bubuko.com,布布扣
 1 public class PJProgressListener implements ProgressListener {
 2     private HttpSession session;
 3     public PJProgressListener() {
 4     }
 5     public PJProgressListener(HttpSession _session) {
 6         session = _session;
 7         ProgressEntity ps = new ProgressEntity();
 8         session.setAttribute("upload_ps", ps);
 9     }
10     public void update(long pBytesRead, long pContentLength, int pItems) {
11         ProgressEntity ps = (ProgressEntity) session.getAttribute("upload_ps");
12         ps.setpBytesRead(pBytesRead);
13         ps.setpContentLength(pContentLength);
14         ps.setpItems(pItems);
15         double mBytes = pBytesRead;
16         double total = pContentLength;
17         if (total <= 0)
18             return;
19         double read = (mBytes / total);
20         read = read * 98;
21         DecimalFormat df = new DecimalFormat("#");
22         Integer result = Integer.parseInt(df.format(read));
23         //更新上传进度
24         session.setAttribute("read",result );
25     }
26 
27     /**
28      * 文件上传进度信息
29      * 
30      * @author Van
31      * 
32      */
33     public class ProgressEntity {
34         private long pBytesRead = 0L;
35         private long pContentLength = 0L;
36         private int pItems;
37 
38         public long getpBytesRead() {
39             return pBytesRead;
40         }
41 
42         public void setpBytesRead(long pBytesRead) {
43             this.pBytesRead = pBytesRead;
44         }
45 
46         public long getpContentLength() {
47             return pContentLength;
48         }
49 
50         public void setpContentLength(long pContentLength) {
51             this.pContentLength = pContentLength;
52         }
53 
54         public int getpItems() {
55             return pItems;
56         }
57 
58         public void setpItems(int pItems) {
59             this.pItems = pItems;
60         }
61 
62         @Override
63         public String toString() {
64             return "ProgressEntity [pBytesRead=" + pBytesRead + ", pContentLength=" + pContentLength + ", pItems=" + pItems + "]";
65         }
66     }
67 
68 }
View Code

3.修改springMVC默认的CommonsMultipartResolver为自定义的:

bubuko.com,布布扣
1 <bean id="multipartResolver"
2     class="cn.bluemobi.util.fileUplaod.PJCommonsMultipartResolver">
3     <property name="maxUploadSize" value="2147483648" />
4     <property name="maxInMemorySize" value="4096" />
5 </bean>
View Code

4.写一个接口读取session里更新的文件上传进度:

bubuko.com,布布扣
 1 /**
 2  * 前台获取进度方法
 3  */
 4 @RequestMapping("file/getUploadProgress")
 5 public void getFileUplaodPreogress(){
 6     Map<String, Object> map = new HashMap<String, Object>();
 7     try {
 8         Integer pre = (Integer) session.getAttribute("read");
 9         map.put(DATA, pre);
10     } catch (Exception e) {
11         e.printStackTrace();
12     } finally{
13         outJSON(map);
14     }
15 }
View Code

5.页面上传进度显示:

bubuko.com,布布扣
  1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2 <!DOCTYPE html>
  3 <html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml">
  4 <head>
  5 <meta charset="UTF-8">
  6 <title>上传文件</title>
  7 <link id="easyuiTheme" rel="stylesheet" href="resource/js/jquery-easyui-1.3.5/themes/default/easyui.css" type="text/css"/>
  8 <link type="text/css" rel="stylesheet" href="resource/css/icon.css"/>
  9 <link rel="stylesheet" type="text/css" href="resource/css/basic.css"/>
 10 <script src="resource/jquery-1.7.2.min.js" type="text/javascript"></script>
 11 <script type="text/javascript" src="resource/js/jquery.easyui.min.js"></script>
 12 <script type="text/javascript" src="resource/js/easyui-lang-zh_CN.js"></script>
 13 <script type="text/javascript" src="resource/js/ajaxfileupload.js"></script>
 14 </head>
 15 <body class="easyui-layout">
 16     <div align="left" data-options="region:‘center‘,border:false" style="padding-left:20px;padding-right:20px;">
 17         <table width="500" border="0" align="center" cellpadding="1" cellspacing="1">
 18             <tr>
 19                 <td nowrap align="right">上传文件:</td>
 20                 <td align="left">
 21                 <input type="file" id="file" name="file" style="width: 150px;" onchange="ajaxFileUpload()">
 22                 <span id="add_span_video" style="width:250px;color:red;"></span>
 23                 </td>
 24             </tr>
 25             <tr>
 26                 <td align="right">上传地址:</td>
 27                 <td align="left"><input id="fileSrc" type="text" style="width:450px;"/></td>
 28             </tr>
 29         </table>
 30     </div>
 31     
 32     <!-- 进度条框框 -->
 33     <div id="progressBar_dialog" class="easyui-dialog" title="上传进度">
 34         <table style="padding: 5px;padding-top: 10px;" cellspacing="0" cellpadding="0" border="0">
 35             <tr>
 36                 <td>
 37                     <div id="progressNumber" class="easyui-progressbar" style="width: 400px;"></div>
 38                 </td>
 39             </tr>
 40         </table>
 41     </div>
 42     
 43     
 44     <script type="text/javascript">
 45         //文件上传
 46         var intel;
 47         function ajaxFileUpload() {
 48             //打开上传进度条的dialog
 49             $(#progressBar_dialog).dialog({
 50                 closed : false
 51             });
 52             //打开定时器,获取文件上传进度
 53             intel = window.setInterval("getPro()", 100);
 54             
 55             //开始上传
 56             $.ajaxFileUpload({
 57                 url:fileadmin/uploadVideo.htm, //需要链接到服务器地址
 58                 secureuri : false,
 59                 fileElementId : file, //文件选择框的name和id属性
 60                 dataType : json, //服务器返回的格式,可以是json
 61                 data:{fileType:1},
 62                 success : function(data) { //相当于java中try语句块的用法
 63                     data = data.replace(/<[^>].*?>/g, "");//对返回的数据进行转换
 64                     data = eval("(" + data + ")");//对返回的数据进行转换
 65                     var src = data.data;
 66                     $("#fileSrc").val(src);
 67                     $.message.alert("提示","上传成功!");
 68                 }
 69             });
 70         }
 71         
 72         //读取进度条信息
 73         function getPro() {
 74             $.ajax({
 75                 type : "post",
 76                 url :file/getUploadProgress.htm,
 77                 success : function(msg) {
 78                     msg = msg.replace(/<[^>].*?>/g, "");//对返回的数据进行转换
 79                     msg = eval("(" + msg + ")");//对返回的数据进行转换
 80                     var data = msg.data;
 81                     $(#progressNumber).progressbar(setValue, Math.floor(data));
 82                     if (Math.floor(data) == 100) {
 83                         $(#progressBar_dialog).dialog({
 84                             closed : true
 85                         });
 86                         window.clearInterval(intel);
 87                     }
 88                 }
 89             });
 90         }
 91         
 92         $(function() {
 93             //进度条对话框初始化
 94             $(#progressBar_dialog).dialog({
 95                 title : 上传进度,
 96                 width : 460,
 97                 height : 80,
 98                 closed : true,
 99                 cache : false,
100                 modal : true,
101                 closable : false,
102                 resizable : false,
103             });
104         });
105         
106     </script>
107 </body>
108 </html>
View Code

 

这种方式是我最初想到和做出来的,内网测试上传图片等小文件没有问题,但是上传了一个1G多大的文件的时候就出现问题啦。文件上传成功,进度条也正常显示了,上传后的文件路径也返回了,但是在页面没有接收到返回的路径。究其原因,是因为页面开了两个ajax同时请求,然后返回结果冲突了。几经周折,于是乎又寻求到了如下的第二种方式。

 

方式二 使用ajaxForm:

只有一个步骤:

bubuko.com,布布扣
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <!DOCTYPE html>
 3 <html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml">
 4 <head>
 5 <meta charset="UTF-8">
 6 <title>上传文件</title>
 7 <link id="easyuiTheme" rel="stylesheet"
 8     href="resource/js/jquery-easyui-1.3.5/themes/default/easyui.css"
 9     type="text/css" />
10 <link type="text/css" rel="stylesheet" href="resource/css/icon.css" />
11 <link rel="stylesheet" type="text/css" href="resource/css/basic.css" />
12 <script src="resource/jquery-1.7.2.min.js" type="text/javascript"></script>
13 <script type="text/javascript" src="resource/js/jquery.easyui.min.js"></script>
14 <script type="text/javascript" src="resource/js/easyui-lang-zh_CN.js"></script>
15 <script type="text/javascript" src="resource/js/ajaxfileupload.js"></script>
16 </head>
17 <body class="easyui-layout">
18     <div align="left" data-options="region:‘center‘,border:false"
19         style="padding-left: 20px; padding-right: 20px;">
20         <form id="fileForm" action="file/uploadFile.htm?fileType=2"
21             method="post" enctype="multipart/form-data">
22             <div>
23                 <input id="img" name="file" type="file" onchange="doSubmit(this)">
24                 <input id="fileUrl" type="text">
25             </div>
26         </form>
27     </div>
28 
29     <!-- 进度条框框 -->
30     <div id="progressBar_dialog" class="easyui-dialog" title="上传进度">
31         <table style="padding: 5px; padding-top: 10px;" cellspacing="0" cellpadding="0" border="0">
32             <tr>
33                 <td>
34                     <div id="progressNumber" class="easyui-progressbar" style="width: 400px;"></div>
35                 </td>
36             </tr>
37         </table>
38     </div>
39 
40     <script type="text/javascript">
41         var fileId;
42         function doSubmit(target){
43             fileId = $(target).attr("id");
44             $("#fileForm").submit();
45         }
46         $(function() {
47             //进度条对话框初始化
48             $(#progressBar_dialog).dialog({
49                 title : 上传进度,
50                 width : 460,
51                 height : 80,
52                 closed : true,
53                 cache : false,
54                 modal : true,
55                 closable : false,
56                 resizable : false
57             });
58 
59             $("#fileForm").ajaxForm({
60                 dataType : "json",
61                 beforeSend : function() {//上传之前设置,在这里可以写验证
62                     $(#progressBar_dialog).dialog({
63                         closed : false
64                     });
65                 },
66                 uploadProgress : function(event, position, total,
67                         percentComplete) {//进度条
68                     $(#progressNumber).progressbar(setValue,
69                             percentComplete);
70                 },
71                 success : function(data) {//成功之后执行
72                     var fileInput = $("#" + fileId);
73                     fileInput.after(fileInput.clone().val(""));
74                     fileInput.remove();
75                     $("#fileUrl").val(data.data);
76                 },
77                 complete : function(data) {
78                     $(#progressBar_dialog).dialog({
79                         closed : true
80                     });
81                 }
82             });
83         });
84     </script>
85 </body>
86 </html>
View Code

 

个人认为第二种方式简单轻便,不需要在后台写监听,更改配置文件,更不需要自己开启网页定时器了,比较喜欢。

SpringMVC文件上传的两种方式

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/shyma/p/4148293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!