zoukankan      html  css  js  c++  java
  • struts2文件上传大小

    --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>

  • 相关阅读:
    TOJ 3660 家庭关系
    TOJ 2857 Stockbroker Grapevine
    关于字符串不为空 错误:s!=null
    根据判断数组不为空然后取他的值----数组不会为空---只能判断其size是否大于0
    JRebel 7.1.5 插件下载 安装 激活 结合 IntelliJ IDEA--自动编译进行热部署---
    @requestbody---接受前端传json对象并绑定javabean
    json转换时区问题-------前端展示时间少8小时--解决方法
    使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件(转)-----https://www.cnblogs.com/smileberry/p/4145872.html
    数据库设计软件介绍--几种数据库建模工具推荐(包含开源版)
    mysql 查询当天、本周,本月,上一个月的数据---https://www.cnblogs.com/benefitworld/p/5832897.html
  • 原文地址:https://www.cnblogs.com/highriver/p/2065557.html
Copyright © 2011-2022 走看看