struts2文件上傳大小限制問題小結


一:首先看一下程序執行中出現的對應報錯信息,如下所示:

[WARN ] 2015-03-03 15:31:11 :Unable to parse request
    org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (78871114) exceeds the configured maximum (52428800)     at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:937)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.parseRequest(JakartaMultiPartRequest.java:151)
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.processUpload(JakartaMultiPartRequest.java:90)
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.parse(JakartaMultiPartRequest.java:80)
    at org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper.<init>(MultiPartRequestWrapper.java:75)
    at org.apache.struts2.dispatcher.Dispatcher.wrapRequest(Dispatcher.java:740)
    at org.apache.struts2.dispatcher.ng.PrepareOperations.wrapRequest(PrepareOperations.java:131)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:83)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.frame.action.ChineseFilter.doFilter(ChineseFilter.java:66)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)
[WARN ] 2015-03-03 15:31:11 :Could not find token name in params.

類似的問題相信很多人都遇到過,也曉得如何解決,我這里記錄下來也是為了讓自己對這個問題理解的更好一點,當然,我下面記錄的情況都是在我的機器上實際都試驗了的,下面是我根據自己的實驗以及網上的相關資料的小結。

 

二:限制Struts2文件上傳的三種情況

     1:Struts2對應的配置文件中的配置的限制

          struts.multipart.maxSize=上傳文件的最大值(單位是字節)這個配置是控制整個項目一次性上傳的文件的最大值!如果實際上傳的文件超過了此配置的大小那么就會報  org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (78871114) exceeds the configured maximum (52428800),這個異常信息!

這個配置有對應的默認值,如果不設置則使用默認的設置(針對我自己的項目這個默認配置的所在位置是:struts2-core-2.3.1.2.jar包中的org\apache\struts2\default.properties文件中)struts.multipart.maxSize=2097152,代表默認上傳的文件最大值是2M,如果我們想修改它也是很容易的,有以下兩種方式:

1)在struts.properties文件中配置,比如:struts.multipart.maxSize=52428800 (代表上傳的文件的最大值是50M)

2)在struts.xml文件中配置,比如:<constant name="struts.multipart.maxSize" value="52428800"/>(也代表上傳的文件的最大值是50M)

 

     2:Struts2對應的文件上傳的攔截器的限制

        <interceptor-ref name="fileUpload">                
              <param name="maximumSize">52428800</param>                
        </interceptor-ref>

 

        這種方式是限制特定的Action的一種方式,當然她是在滿足第一種情況下才起作用的,換言之,這里的配置要小於第一種情況的設置才能起到對應的作用!

需要注意的是,攔截器的使用以及和第一種文件上傳之間的配合,情況如下(下面的代碼僅僅是事例代碼而已):

        2-1:沒有攔截器的情況,僅第一種限制起作用

        <action name="fileUpload" class="fileUploadAction" method="fileUpload">        
        </action>  

        2-2:僅使用默認的攔截器的情況,和2-1的效果一樣,它們兩個的本質是一樣的,因為Struts2會每個Action加入一個默認的攔截器,顯示說明與否皆可!

        <action name="fileUpload" class="fileUploadAction" method="fileUpload">    
            <interceptor-ref name="defaultStack"></interceptor-ref>                 
        </action> 

        2-3:僅使用文件上傳的攔截器的情況,第一種限制起作用,第二種限制也有效果,不過這種使用攔截器的方式是有問題的,這里僅僅使用了文件上傳的攔截器而已,導致數據信息的丟失!當實際上傳的文件大於攔截器的配置的時候,會報[WARN ] 2015-03-03 18:49:44 :File too large: fileUploadModel.upload "test.png" "upload_6e4dba7d_14be260bb68__7fe3_00000018.tmp" 11185361)不過程序會繼續的執行!

        <action name="fileUpload" class="fileUploadAction" method="fileUpload">  
            <interceptor-ref name="fileUpload">                
                  <param name="maximumSize">10485760</param>                
            </interceptor-ref>               
        </action>  

  

        2-4:先使用文件上傳的攔截器,再使用默認的攔截器的情況,第一種限制起作用,第二種限制也起作用,並且當實際上傳的文件的大小超過攔截器的限制時,程序會報錯[WARN ] 2015-03-03 18:53:30 :File too large: fileUploadModel.upload "test.png" "upload_53477faa_14bdea02616__7fef_00000008.tmp" 11185361)且程序會終止執行(調試的結果顯示沒有進入相應的Action類中)!

        <action name="fileUpload" class="fileUploadAction" method="fileUpload"> 
            <interceptor-ref name="fileUpload">                
                  <param name="maximumSize">10485760</param>                
            </interceptor-ref>              
            <interceptor-ref name="defaultStack"></interceptor-ref>                 
        </action>  

 

        2-5:先使用默認的攔截器,再使用文件上傳的攔截器的情況,第一種限制起作用,第二種限制也起作用,不過當超過攔截器的限制時,程序會報錯[WARN ] 2015-03-03 18:58:30 :File too large: fileUploadModel.upload "test.png" "upload_53477faa_14bdea02616__7fef_00000008.tmp" 11185361)不過仍繼續的執行!

        <action name="fileUpload" class="fileUploadAction" method="fileUpload">             
            <interceptor-ref name="defaultStack"></interceptor-ref>                 
            <interceptor-ref name="fileUpload">                
                  <param name="maximumSize">10485760</param>                
            </interceptor-ref>              
        </action>  

 

    3:上傳文件的最大限制

          文件上傳的最大值應<2G,無論前面兩項配置的是多大,當實際上傳的文件大小大於2G的時候就會出現如下圖的情況:

針對這個情況,我還不明白是什么原因引起的,如果有清楚的請告知一下,非常感謝!

 

三:對應的源碼的情況

     第一種限制對應的關鍵性源碼(位置:commons-fileupload-1.2.2.jar包下\org\apache\commons\fileupload\FileUploadBase.java)

FileItemIteratorImpl(RequestContext ctx)
      throws FileUploadException, IOException
    {
      if (ctx == null) {
        throw new NullPointerException("ctx parameter");
      }

      String contentType = ctx.getContentType();
      if ((null == contentType) || (!contentType.toLowerCase().startsWith("multipart/")))
      {
        throw new FileUploadBase.InvalidContentTypeException("the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is " + contentType);
      }

      InputStream input = ctx.getInputStream();

      if (FileUploadBase.this.sizeMax >= 0L) {
        int requestSize = ctx.getContentLength();
        if (requestSize == -1)
          input = new LimitedInputStream(input, FileUploadBase.this.sizeMax, FileUploadBase.this) { private final FileUploadBase val$this$0;

            protected void raiseError(long pSizeMax, long pCount) throws IOException { FileUploadException ex = new FileUploadBase.SizeLimitExceededException("the request was rejected because its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax);

              throw new FileUploadBase.FileUploadIOException(ex);
            }
          };
        //看這里
else if ((FileUploadBase.this.sizeMax >= 0L) && (requestSize > FileUploadBase.this.sizeMax)) { throw new FileUploadBase.SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + FileUploadBase.this.sizeMax + ")", requestSize, FileUploadBase.this.sizeMax); } } String charEncoding = FileUploadBase.this.headerEncoding; if (charEncoding == null) { charEncoding = ctx.getCharacterEncoding(); } this.boundary = FileUploadBase.this.getBoundary(contentType); if (this.boundary == null) { throw new FileUploadException("the request was rejected because no multipart boundary was found"); } this.notifier = new MultipartStream.ProgressNotifier(FileUploadBase.this.listener, ctx.getContentLength()); this.multi = new MultipartStream(input, this.boundary, this.notifier); this.multi.setHeaderEncoding(charEncoding); this.skipPreamble = true; findNextItem(); }

 

     第二種限制對應的關鍵性源碼(位置:struts2-core-2.3.1.2.jar包下\org\apache\struts2\interceptor\FileUploadInterceptor.java)

  protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale)
  {
    boolean fileIsAcceptable = false;

    if (file == null) {
      String errMsg = getTextMessage(action, "struts.messages.error.uploading", new Object[] { inputName }, locale);
      if (validation != null) {
        validation.addFieldError(inputName, errMsg);
      }

      if (LOG.isWarnEnabled())
        LOG.warn(errMsg, new String[0]);
    }
    //看這里
else if ((this.maximumSize != null) && (this.maximumSize.longValue() < file.length())) { String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new Object[] { inputName, filename, file.getName(), "" + file.length() }, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) LOG.warn(errMsg, new String[0]); } else if ((!this.allowedTypesSet.isEmpty()) && (!containsItem(this.allowedTypesSet, contentType))) { String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new Object[] { inputName, filename, file.getName(), contentType }, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) LOG.warn(errMsg, new String[0]); } else if ((!this.allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(this.allowedExtensionsSet, filename))) { String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new Object[] { inputName, filename, file.getName(), contentType }, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) LOG.warn(errMsg, new String[0]); } else { fileIsAcceptable = true; } return fileIsAcceptable; }

 

 四:參考的網絡資源如下

1)Struts2文件上傳大小限制相關

http://www.cnblogs.com/highriver/archive/2011/06/01/2065557.html

http://www.cnblogs.com/forlina/archive/2011/09/08/2171404.html

http://www.docin.com/p-633913742.html

 2)Struts2攔截器相關

http://struts2.group.iteye.com/group/wiki/1397-deep-into-struts2-interceptors

http://www.open-open.com/lib/view/open1338339244354.html

http://blog.csdn.net/qjyong/article/details/1824607


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM