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

时间: 2024-10-06 15:40:47

struts2文件上传大小限制问题小结的相关文章

struts2文件上传大小限制问题

struts2默认文件上传大小为2M,如需修改默认大小,解决方法如下: <struts> <constant name="struts.multipart.maxSize" value="20971520" /> <!-- 设置允许最大值 20MB(1024*1024*20) --> <package name="build" extends="struts-default">

struts2设置文件上传大小

利用struts2想要设置或者限制上传文件的大小,可以在struts.xml配置文件里面进行如下配置: <constant name="struts.multipart.maxSize" value="10000000" /> 上面这句话的意思是设置文件上传大小,最大不超过9.8M.计算方式如下: 设置上次文件的大小最大为10000000字节也就是(10000000/1024/1024)=9.5MB

struts2 文件上传下载

四.文件的上传(拦截器)和下载(stream结果类型)(需要练一遍) 1.文件上传 必要前提: a.表单method必须是post: b.enctype取值必须是multipart/form-data: c.提供文件选择域. 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib uri="/struts-t

struts2文件上传突破2M限制

strutsuploadfileactionclass struts配置文件 [html] view plaincopyprint? 1. <action name="FileUpload" class="cn.timefly.strutsTest.FileUploadAction">   2.     <result name="success">/FileUploadResult.jsp</result> 

struts2学习(13)struts2文件上传和下载(1)

一.Struts2文件上传: 二.配置文件的大小以及允许上传的文件类型: 三.大文件上传: 如果不配置上传文件的大小,struts2默认允许上传文件最大为2M: 2097152Byte: 例子实现: com.cy.action.FileUploadAction.java: package com.cy.action; import java.io.File; import org.apache.commons.io.FileUtils; import com.opensymphony.xwork

【SSH2(实践篇)】--Struts2文件上传下载实例

上篇文章又一次回顾了Struts2的运行机制,对它的运行步骤做了一步步的解析,这个解析不但再一次理清了Struts2的使用方法,而且对它的映射机制进行了深入的解析,并在最后通过一个实例来介绍了Struts2的一种使用方法,这里将做一个有关文件上传下载的实例. 一.文件上传 Struts2并没有提供文件上传的组件,所以想要实现上传的功能就必须通过第三方组件来实现,在Struts2引用的jar中包含了文件上传的组件,它是通过commons-fileupload.jar和commons-io.jar来

Spring MVC环境中文件上传大小和文件类型限制以及超大文件上传bug问题

    在上一篇文章中,主要介绍了Spirng MVC环境下的正常情况下文件上传功能实现.在实际开发的时候,还会涉及到上传文件大小和类型的限制,接下来就会对Spirng MVC环境下文件上传大小和类型的限制进行介绍,还会讲解到文件上传大小tomcat服务器bug问题及解决方案. 一.文件上传大小限制 这里还是接着上篇文章先介绍Spring MVC下的文件上传大小限制,文件上传大小的限制在springmvc-config.xml中配置文件解析器CommonsMultipartResolver时即可

Struts2文件上传带进度条,虽然不是很完美

好久没有写东西,最近在做个项目,要用到文件h 传的,以前虽然也做上传,但是总觉得不好用 ,现在和队友合作做了一个带进度条的上传,觉得还行~~和大家分享一下. 首先说一下大概是这样实现的,在我们平时的上传表单里面,除了文件上传之外,也许还有其他的信息需要填写的,这样问题就来了:点击上传按钮之后,这个表单都封装并提交上去了,在上传完成后整个页面就跳转了.而且也不利于我们验证用户输入.很多人这样做的,把这2个操作分开,当然这样也行... 我们这样做:一个普通页面(可以用于填写所有信息的),一个文件上传

分享知识-快乐自己:Struts2文件上传及文件下载

1)Struts2单文件上传 action:类文件 package com.mlq.action; import com.opensymphony.xwork2.ActionSupport; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import java.io.File; import java.io.IOException; /** * Struts2:单文件