spring mvc CommonsMultipartResolver上传文件异常处理
近期已经上线的项目出现了一个异常
严重: Servlet.service() for servlet JeeCmsAdmin threw exception org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (2152078) exceeds the configured maximum (2097152) at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:914) at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349) at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126) at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:155) at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:138)
这个异常是由于上传文件过大引起来的,这里指的是上传文件的总量,而不是单个的文件。
由于之前已经对上传文件在控制器进行过单个验证,但是此异常是在请求还未到达控制器的时候就已经被spring容器捕获抛出异常了,故无法在控制器对进行文件校验
<bean id="multipartResolver" class="com.sinolife.sf.framework.comm.CommonsMultipartResolver"> <property name="maxUploadSize" value="50946048" /> <property name="resolveLazily" value="true"/> </bean>
这时就想在前台对文件进行大小校验,但是由于需要兼容的浏览器较多,纯前端代码无法完全适应浏览器的兼容器,不得不放弃放弃了JS校验。
最后在控制器中使用注解拦截了异常,对其进行处理
@ExceptionHandler(MaxUploadSizeExceededException.class) public String handleException(Exception ex,HttpServletRequest request,HttpServletResponse response) { StringBuffer sb = new StringBuffer(); // sb.append("<script language='javascript'>history.go(-1);alert('"); // if (ex instanceof org.springframework.web.multipart.MaxUploadSizeExceededException){ // sb.append("文件大小不应大于"+getFileKB(((MaxUploadSizeExceededException)ex).getMaxUploadSize())); // } // sb.append("');"); // sb.append("</script>"); // // try { // System.out.println(sb.toString()); // response.setContentType("text/html; charset=utf-8"); // response.getWriter().println(sb.toString()); // response.getWriter().flush(); // } catch (IOException e) { // e.printStackTrace(); // } // return; }
这样虽然捕获了异常,对其进行了处理,但是用户体验不怎么好,下一篇利用iframe实现无刷新上传处理
最后再给出起初利用JS进行文件大小校验的代码
<img alt="" src="" id="temping" style="display: none;"> var maxsize = 10*1024*1024;//2M var errMsg = "上传的附件文件不能超过2M!!!"; var tipMsg = "您的浏览器暂不支持计算上传文件的大小,确保上传文件不要超过2M,建议使用IE、FireFox、Chrome浏览器。"; var browserCfg = {}; var ua = window.navigator.userAgent; if (ua.indexOf("MSIE")>=1){ browserCfg.ie = true; }else if(ua.indexOf("Firefox")>=1){ browserCfg.firefox = true; }else if(ua.indexOf("Chrome")>=1){ browserCfg.chrome = true; } try{ var obj_file = document.getElementById("chargeFront"); if(obj_file.value==""){ alert("请先选择上传文件"); return; } var filesize = 0; if(browserCfg.firefox || browserCfg.chrome ){ filesize = obj_file.files[0].size; }else if(browserCfg.ie){ var obj_img = document.getElementById('temping'); alert('浏览器判断2' + obj_file.value); obj_img.src =obj_file.value; filesize = obj_img.fileSize; alert(filesize); var fso,f,fname,fsize; var flength=40000; //设置上传的文件最大值(单位:kb),超过此值则不上传。 fso=new ActiveXObject("Scripting.FileSystemObject"); f=fso.GetFile(obj_file.value);//文件的物理路径 fsize=f.Size; //文件大小(bit) fsize=fsize/1024; //去掉注释,可以测试 alert("文件路径:"+f); alert("文件名:"+fname); alert("文件大小:"+fsize+"kb"); }else{ alert("非IE 谷歌" + tipMsg); return; } if(filesize==-1){ alert("-1的情况"+tipMsg); return; }else if(filesize>maxsize){ alert("不是-1的情况" + errMsg); return; }else{ alert("文件大小符合要求"); return; } }catch(e){ alert(e); }
博客地址:http://qiaoyihang.iteye.com/