最近项目需要加一个问答功能,其中在写struts2上传附件的时候,老是出一些莫名其妙的错:

  其中,最关键的原因是的struts2默认的文件大小2M,如何突破这个限制,上传一定范围内大小的附件呢

  出现的错误有如下:
1、2012-02-24 11:06:31,937 ERROR (org.apache.struts2.dispatcher.Dispatcher:512) - Could not find action or result
No result defined for action com.iman.portal.action.QuestionActionImpl and result problemPage - action - file:/E:/myeclipse/workspaces/portal/WebRoot/WEB-INF/classes/struts2/struts-question.xml:51:55

2、the request was rejected because its size (2973652) exceeds the configured maximum (2097152)
中文意思: 要求被拒绝,因为它的大小(2973652)超过配置的最大值(2097152)、

  考虑到用户体验,所以必须在上传附件时,拦截这样的异常,解决方法如下:

1、所上传的文件,在上传过程中都是先存放在缓存中的,安全起见,还是在项目的struts.properties文件中,加一个临时存放路径,虽然项目中己经设置好服务器的物理路径。
  
   struts.multipart.saveDir=/temp

2、考虑到后期可能会修改文件上传的大小,所以不管是否默认,还是在项目的struts.properties文件中,加如下配置:

    <!-- 所允许上传文件的大小2M -->
    <constant name="struts.multipart.maxSize" value="2097152"/>

3、struts.xml配置

<!-- 修改问题方法 --> 
 
     <action name="updateProblem" method="updateProblem"> 
 
       <interceptor-ref name="fileUpload"/>  
 
       <interceptor-ref name="defaultStack" />  
 
      <result name="input">/page/question/page/problemPage.jsp</result>  
 
     </action>



4、最重要也是最关键的一步

   fileUpload拦截器只是当文件上传到服务器上之后,才进行的文件类型和大小判断。在Action中如果我们什么操作都不做的话,异常就会展现在用户的面前,因此想了一个方法,把该异常信息设置为Action级别的错误信息。即重写addActionError方法。

@Override 
 
    public void addActionError(String anErrorMessage) { 
 
     // 这里要先判断一下,是我们要替换的错误,才处理 
 
     if (anErrorMessage.startsWith("the request was rejected because its size")) { 
 
         Pattern pattern = Pattern.compile("\\d+"); 
 
         Matcher m = pattern.matcher(anErrorMessage); 
 
         // 匹配一次 
 
         m.find();         
 
         String s1 =m.group();//上传的文件大小 
 
         // 再匹配一次 
 
         m.find();         
 
         String s2 =m.group();//所限制的大小             
 
         if(!s1.equals("") && !s2.equals("")){ 
 
             fileUploadErrorMessage="你上传的文件大小(" +  Long.valueOf(s1)/1024 +"字节)超过允许的大小(" + Long.valueOf(s2)/1024/1024 + "M)"; 
 
             getRequest().setAttribute("fileUploadErrorMessage","文件太大,超过了允许的大小("+Long.valueOf(s2)/1024/1024+"M),上传失败!"); 
 
             // 将信息替换掉 
 
             super.addActionError(fileUploadErrorMessage); 
 
             } 
 
         } else {// 否则按原来的方法处理 
 
             super.addActionError(anErrorMessage); 
 
         } 
 
     }


    可以,在返回页面用<s:fielderror/> <s:fielderror/>,得到addActionError中的错误内容。
    因为我不打算,在页面上显示出来错误原因,想弹出一个提示框,所以将信息放入了request对象中。
    而页面加载时,加了如下js验证:

//判断 文件是否上传成功 
 
     var message="${request.fileUploadErrorMessage}"; 
 
         if(message!=null && ""!=trim(message) && message!="null"){ 
 
             self.parent.diag.close(); 
 
         alert(message); 
 
         return; 
 
     }



下面是一些参考了解东东:

struts.multipart.maxSize掌控整个项目所上传文件的最大的Size
struts.multipart.maxSize和fileUpload拦截器的maximumSize属性分工不同,总结如下:
1.struts.multipart.maxSize掌控整个项目所上传文件的最大的Size。
  超过了这个size,后台报错,程序处理不了如此大的文件。fielderror里面会有如下的提示:
  the request was rejected because its size (16272982) exceeds the configured maximum (9000000)
2.fileUpload拦截器的maximumSize属性必须小于struts.multipart.maxSize的值。
  struts.multipart.maxSize默认2M,当maximumSize大于2M时,必须设置struts.multipart.maxSize的值大于maximumSize。
3.当上传的文件大于struts.multipart.maxSize时,系统报错
  当上传的文件在struts.multipart.maxSize和maximumSize之间时,系统提示:
  File too large: file "MSF的概念.ppt" "upload__5133e516_129ce85285f__7ffa_00000005.tmp" 6007104 
  当上传的文件小于maximumSize,上传成功。

<action name="UploadFile" class="com.buptisc.srpms.action.UploadFileAction"> 
 
             <result name="UploadFileResult">/pages/ShowOtherFiles.jsp</result> 
 
             <result name="JGBsuccess">/pages/JGBdetail.jsp</result> 
 
             <interceptor-ref name="fileUpload"> 
 
                 <param name="savePath">/data</param>   
 
                 <param name="maximumSize">52428800</param>  
 
             </interceptor-ref> 
 
             <interceptor-ref name="defaultStack"></interceptor-ref> 
 
 </action>