strust2文件上传大小处理问题

转载 2012年03月29日 18:23:18

--struts2中文件上传的二个限制,一个是struts.multipart.maxSize,如果不设置,struts2 的核心包下的default.properties文件里有默认的大小设置struts.multipart.maxSize=2097152,即2M. 这是struts2文件上传的第一道关.

第二道关是inteceptor中的maximumSize. 当真实的文件大小能通过第一道关时.针对不同的action中配置的inteceptor,maximumSize才能发挥相应的拦截作用.

比如struts.multipart.maxSize=50M. actionA中inteceptorA的maximumSize=30M. actionB中inteceptorB的maximumSize=10M.

struts.multipart.maxSize=50M对于inteceptorA,B都会起到第一关的作用.而inteceptorA和inteceptorB可以在通过第一关之后,根据自己的业务定制各自针对拦截器起作用的maximumSize

如果真实的文件>50M. 抛出会抛出the request was rejected because its size (XXXX) exceeds the configured maximum (XXXX)异常,他是不能被国际化的,因为这个信息是commons-fileupload组件抛出的,是不支持国际化这信息.

struts2.2 org.apache.commons.fileupload.FileUploadBase.java中

/**
/**
  * Creates a new instance.
  * @param ctx The request context.
  * @throws FileUploadException An error occurred while
  *   parsing the request.
  * @throws IOException An I/O error occurred.
  */  
 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 InvalidContentTypeException(  
                 "the request doesn't contain a "  
                 + MULTIPART_FORM_DATA  
                 + " or "  
                 + MULTIPART_MIXED  
                 + " stream, content type header is "  
                 + contentType);  
     }  
   
     InputStream input = ctx.getInputStream();  
   
     if (sizeMax >= 0) {  
         int requestSize = ctx.getContentLength();  
         if (requestSize == -1) {  
             input = new LimitedInputStream(input, sizeMax) {  
                 protected void raiseError(long pSizeMax, long pCount)  
                         throws IOException {  
                     FileUploadException ex =  
                         new SizeLimitExceededException(  
                             "the request was rejected because"  
                             + " its size (" + pCount  
                             + ") exceeds the configured maximum"  
                             + " (" + pSizeMax + ")",  
                             pCount, pSizeMax);  
                     throw new FileUploadIOException(ex);  
                 }  
             };  
         } else {  
 ///问题就在这里////////////////////////////////////  
             if (sizeMax >= 0 && requestSize > sizeMax) {  
                 throw new SizeLimitExceededException(  
                         "the request was rejected because its size ("  
                         + requestSize  
                         + ") exceeds the configured maximum ("  
                         + sizeMax + ")",  
                         requestSize, sizeMax);  
             }  
         }  
     }  
   
     String charEncoding = headerEncoding;  
     if (charEncoding == null) {  
         charEncoding = ctx.getCharacterEncoding();  
     }  
   
     boundary = getBoundary(contentType);  
     if (boundary == null) {  
         throw new FileUploadException(  
                 "the request was rejected because "  
                 + "no multipart boundary was found");  
     }  
   
     notifier = new MultipartStream.ProgressNotifier(listener,  
             ctx.getContentLength());  
     multi = new MultipartStream(input, boundary, notifier);  
     multi.setHeaderEncoding(charEncoding);  
   
     skipPreamble = true;  

     findNextItem();

如果InteceptorA上传的是40M的真实文件.那么此时拦截器InteceptorA会访问国际化信息:struts.messages.error.file.too.larges对应的值.

当且仅当上传文件<=30M的时候,InteceptorA才会成功上传.

下面是解决struts.multipart.maxSize提示信息不友好的问题.

当超过50M时.commons-fileupload抛出运行时异常,struts2会把这个异常看到是action级别的异常.所以会将异常信息

the request was rejected because its size (XXXX) exceeds the configured maximum (XXXX)写到actionError里面.我们需要做的就是在action里覆盖addActionError方法


@Override
    public void addActionError(String anErrorMessage) {
        //改从国际化里取值
        if (anErrorMessage
                .startsWith("the request was rejected because its size")) {
            super.addActionError(getText("struts.multipart.maxSize.limit"));
        } else {
            super.addActionError(anErrorMessage);
        }

    }

相应的配置文件

struts.multipart.maxSize.limit=系统上传的文件最大为50M
struts.messages.error.file.too.larges=新广告批量上传的文件最大为5M

struts.messages.error.content.type.not.allowed=上传的文件格式目前仅支持xls格式
struts.messages.error.uploading=上传文件失败
struts.messages.invalid.token=您已经提交了表单,请不要重复提交。
fileupload.filenums.exceed=已经有超过5个文件在运行,请稍候再试
filedownload.rows.exceed=由于您选择的广告组内广告数量太多,请分组下载
accountNotExist=客户不存在
invalidTask=无效的任务

注意,由于inteceptor中途返回,原来页面上输入的其他文本内容也都不见了,也就是说params注入失败。

 

这个是没办法的,因为这个异常是在文件上传之前捕获的,文件未上传,同时params也为注入,所以这时最好重定向到一个jsp文件,提示上传失败,然后重写填写相应信息。

解决办法:最好跳到一个专门显示错误的页.而不要返回操作页.

-------------------------------------------------------------------------------------------

注意,拦截器所谓的同名配置覆盖,是重复执行的,比如defaultStack中是包含fileUpload,token的. 如果将<interceptor-ref name="defaultStack" />放到显示定义的拦截器之后,会覆盖显示定义的拦截器.

下面是正确的拦截器顺序:

<action name="BatchMIADOperation!*" method="{1}"
            class="com.*****.***.action.multiidea.batchad.BatchMIADOperationAction">
            <interceptor-ref name="defaultStack" />
            <interceptor-ref name="fileUpload">
                <param name="maximumSize">5242880</param>
                <!--
                    <param name="allowedTypes">
                    application/vnd.ms-excel
                    </param>
                -->
            </interceptor-ref>
            <interceptor-ref name="token">
                <param name="excludeMethods">
                    init,search,updateBatchCpcMatch,batchExportMIAD,downloadWhenError
                </param>
            </interceptor-ref>
            <result name="input">
                /WEB-INF/jsp/multiidea/batchad/BatchMIAD.jsp
            </result>
            <result name="success">
                /WEB-INF/jsp/multiidea/batchad/BatchMIAD.jsp
            </result>
            <result name="invalid.token">
                /WEB-INF/jsp/multiidea/batchad/BatchMIAD.jsp
            </result>
        </action>



相关文章推荐

strust2 文件上传

上传: 首先我们要明白strust2 的文件上传是通过FileUploadInterceptor来实现的。 其次,在我们jsp页面的form标签中有method提交方式需要时post,然后需要设置...

上传文件细节处理问题(包括中文乱码、限制文件大小、显示上传速度、删除临时文件,随机生成文件夹等)

上传文件细节处理问题 一  中文乱码问题 1.上传文件的中文乱码问题    用解析器的对象去调用setHeaderEncoding方法设置就行     // (1)创建一个解析器工厂   ...

strust2文件上传功能

  • 2013年11月23日 17:19
  • 4KB
  • 下载

strust2文件上传 +包

  • 2010年11月27日 16:46
  • 2.5MB
  • 下载

struts2文件上传大小默认限制问题

struts2中文件上传的二个限制,一个是struts.multipart.maxSize,如果不设置,struts2 的核心包下的default.properties文件里有默认的大小设置strut...

解决Struts2文件上传的大小限制问题

1. 问题描述 背景:本人用eclipse开发一个基于Struts2.3.16.3_Spring4.1.1_Hibernate4.3.6架构的web项目, 需要用到xhEidtor编辑器, 在上传大...

struts2文件上传大小限制问题小结

一:首先看一下程序执行中出现的对应报错信息,如下所示: [WARN ] 2015-03-03 15:31:11 :Unable to parse request org.apache...

struts2文件上传类型和大小提示信息问题

struts2文件上传问题。 之前的博客中针对struts2上传做了介绍,其中就strut2文件上传类型和大小限制做了介绍,基本满足了文件上传的功能。但是上传文件类型不对或者文件超出了大小限制,...
  • nmvbliy
  • nmvbliy
  • 2012年11月08日 21:36
  • 4139

【问题解决】使用Strust2文件上传图片无法显示

Struts2 文件上传功能小Demo,将文件成功地保存在服务器磁盘里,而且上传图片,能够在视图页面用相对路径成功显示...

struts文件上传大小限制问题

  • 2011年03月19日 23:44
  • 10KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:strust2文件上传大小处理问题
举报原因:
原因补充:

(最多只允许输入30个字)