the request was rejected because its size (2877943


  在struts2中咱們上傳文件大於struts.multipart.maxSize設置的值時會拋出the request was rejected because its size (XXXX) exceeds the configured maximum (XXXX)異常,他是不能被國際化的,這信息對應用戶來講是很是不友好的,那任何處理? java

 

在struts2.2 中有兩個地方設置上傳文件大小: apache

   一個是在攔截器fileUpload中設置 服務器

[c-sharp]  view plain copy
  1. <interceptor-ref name="fileUpload">  
  2.   <param name="maximumSize">1000000</param>  
  3. </interceptor-ref>    

   一個是在struts2 自帶的文件default.properties中設置的(系統默認大小2M) 框架

   struts.multipart.maxSize=2097152 jsp

   這個能夠在struts.propertise 文件中修改 ide

 

那這兩個有什麼區別呢? .net

   Struts2框架底層默認用的是apache的commons-fileupload組件對上傳文件進行接受處理。struts.multipart.maxSize設置的大小就是該處理時取用的值,在上傳文件以前系統會去比較文件的大小是否超過了該值,若是超過將拋出上述異常,commons-fileupload組件是不支持國際化的,因此咱們看到的異常都是默認的。 blog

   fileUpload攔截器只是當文件上傳到服務器上以後,才進行的文件類型和大小判斷。 若是上傳的文件大小恰好這struts.multipart.maxSize與maximumSize 之間會拋出 key  struts.messages.error.file.too.large 對應的異常信息,這個才支持國際化。那不是把struts.multipart.maxSize設很大,不就解決問題了嗎?非也! fileUpload攔截器只是當文件上傳到服務器上以後,才進行的文件類型和大小判斷,這樣會形成系統產生多餘沒用的文件。 ip

 

那該如何是好? get

   其實解決的辦法有多種,我這裏介紹種最簡單的方法:
   在struts2.2 org.apache.commons.fileupload.FileUploadBase.java 中咱們看到

 

[c-sharp]  view plain copy
  1. /** 
  2.  * Creates a new instance. 
  3.  * @param ctx The request context. 
  4.  * @throws FileUploadException An error occurred while 
  5.  *   parsing the request. 
  6.  * @throws IOException An I/O error occurred. 
  7.  */  
  8. FileItemIteratorImpl(RequestContext ctx)  
  9.         throws FileUploadException, IOException {  
  10.     if (ctx == null) {  
  11.         throw new NullPointerException("ctx parameter");  
  12.     }  
  13.   
  14.     String contentType = ctx.getContentType();  
  15.     if ((null == contentType)  
  16.             || (!contentType.toLowerCase().startsWith(MULTIPART))) {  
  17.         throw new InvalidContentTypeException(  
  18.                 "the request doesn't contain a "  
  19.                 + MULTIPART_FORM_DATA  
  20.                 + " or "  
  21.                 + MULTIPART_MIXED  
  22.                 + " stream, content type header is "  
  23.                 + contentType);  
  24.     }  
  25.   
  26.     InputStream input = ctx.getInputStream();  
  27.   
  28.     if (sizeMax >= 0) {  
  29.         int requestSize = ctx.getContentLength();  
  30.         if (requestSize == -1) {  
  31.             input = new LimitedInputStream(input, sizeMax) {  
  32.                 protected void raiseError(long pSizeMax, long pCount)  
  33.                         throws IOException {  
  34.                     FileUploadException ex =  
  35.                         new SizeLimitExceededException(  
  36.                             "the request was rejected because"  
  37.                             + " its size (" + pCount  
  38.                             + ") exceeds the configured maximum"  
  39.                             + " (" + pSizeMax + ")",  
  40.                             pCount, pSizeMax);  
  41.                     throw new FileUploadIOException(ex);  
  42.                 }  
  43.             };  
  44.         } else {  
  45. ///問題就在這裏////////////////////////////////////  
  46.             if (sizeMax >= 0 && requestSize > sizeMax) {  
  47.                 throw new SizeLimitExceededException(  
  48.                         "the request was rejected because its size ("  
  49.                         + requestSize  
  50.                         + ") exceeds the configured maximum ("  
  51.                         + sizeMax + ")",  
  52.                         requestSize, sizeMax);  
  53.             }  
  54.         }  
  55.     }  
  56.   
  57.     String charEncoding = headerEncoding;  
  58.     if (charEncoding == null) {  
  59.         charEncoding = ctx.getCharacterEncoding();  
  60.     }  
  61.   
  62.     boundary = getBoundary(contentType);  
  63.     if (boundary == null) {  
  64.         throw new FileUploadException(  
  65.                 "the request was rejected because "  
  66.                 + "no multipart boundary was found");  
  67.     }  
  68.   
  69.     notifier = new MultipartStream.ProgressNotifier(listener,  
  70.             ctx.getContentLength());  
  71.     multi = new MultipartStream(input, boundary, notifier);  
  72.     multi.setHeaderEncoding(charEncoding);  
  73.   
  74.     skipPreamble = true;  
  75.     findNextItem();  
  76. }  

實際上他是把該異常信息設置爲Action級別的錯誤信息。

瞭解完這個就好辦了,咱們能夠在action中直接重寫ActionSupport的addActionError()方法,

 

[c-sharp]  view plain copy
  1. /**   
  2.  
  3. * 替換文件上傳中出現的錯誤信息  
  4. *引用 import java.util.regex.Matcher; 
  5. *    import java.util.regex.Pattern; 
  6. *  
  7. * */   
  8.   
  9. @Override   
  10.   
  11. public void addActionError(String anErrorMessage) {    
  12.   
  13. //這裏要先判斷一下,是咱們要替換的錯誤,才處理    
  14.   
  15.    if (anErrorMessage.startsWith("the request was rejected because its size")) {    
  16.   
  17.      Matcher m = Pattern.compile("//d+").matcher(anErrorMessage);    
  18.   
  19.     String s1 = "";    
  20.   
  21.     if (m.find())   s1 = m.group();    
  22.   
  23.     String s2 = "";    
  24.   
  25.     if (m.find())   s2 = m.group();    
  26.   
  27.     //偷樑換柱,將信息替換掉    
  28.      super.addActionError("你上傳的文件大小(" + s1 + ")超過容許的大小(" + s2 + ")");    
  29.     //也能夠改成在Field級別的錯誤  
  30.     // super.addFieldError("file","你上傳的文件大小(" + s1 + ")超過容許的大小(" + s2 + ")");    
  31.   
  32.   } else {//不然按原來的方法處理   
  33.   
  34.      super.addActionError(anErrorMessage);    
  35. }    
  36.   
  37. }   
 

這時這頁面增長

 

[c-sharp]  view plain copy
  1. <s:fielderror/>  

就能夠了。

 

作到這裏還有個問題,就是原來頁面上輸入的其餘文本內容也都不見了,也就是說params注入失敗。

這個是沒辦法的,由於這個異常是在文件上傳以前捕獲的,文件未上傳,同時params也爲注入,因此這時最好重定向到一個jsp文件,提示上傳失敗,而後重寫填寫相應信息。

相關文章
相關標籤/搜索