您的位置:首页 > 编程语言 > Java开发

struts2中设置上传文件大小

2016-07-19 18:17 375 查看
运行例子时,报错: the request was rejected because its size (2278596) exceeds the configured maximum (2097152)

原因是上传文件过大,需要设置上传文件大小

在struts2.2 中有两个地方设置上传文件大小:

   一个是在拦截器fileUpload中设置

[c-sharp] view
plaincopy

<interceptor-ref name="fileUpload">  

  <param name="maximumSize">1000000</param>  

</interceptor-ref>    

   一个是在struts2 自带的文件default.properties中设置的(系统默认大小2M)

   struts.multipart.maxSize=2097152

   这个可以在struts.propertise 文件中修改

 

那这两个有什么区别呢?

   Struts2框架底层默认用的是apache的commons-fileupload组件对上传文件进行接受处理。struts.multipart.maxSize设置的大小就是该处理时取用的值,在上传文件之前系统会去比较文件的大小是否超过了该值,如果超过将抛出上述异常,commons-fileupload组件是不支持国际化的,所以我们看到的异常都是默认的。

   fileUpload拦截器只是当文件上传到服务器上之后,才进行的文件类型和大小判断。 如果上传的文件大小刚好这struts.multipart.maxSize与maximumSize 之间会抛出 key  struts.messages.error.file.too.large 对应的异常信息,这个才支持国际化。那不是把struts.multipart.maxSize设很大,不就解决问题了吗?非也! fileUpload拦截器只是当文件上传到服务器上之后,才进行的文件类型和大小判断,这样会造成系统产生多余没用的文件。

 

那该如何是好?

   其实解决的办法有多种,我这里介绍种最简单的方法:

   在struts2.2 org.apache.commons.fileupload.FileUploadBase.java 中我们看到

 

[c-sharp] view
plaincopy

/** 

 * 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();  

}  

实际上他是把该异常信息设置为Action级别的错误信息。

了解完这个就好办了,我们可以在action中直接重写ActionSupport的addActionError()方法,

 

[c-sharp] view
plaincopy

/**   

 

* 替换文件上传中出现的错误信息  

*引用 import java.util.regex.Matcher; 

*    import java.util.regex.Pattern; 

*  

* */   

  

@Override   

  

public void addActionError(String anErrorMessage) {    

  

//这里要先判断一下,是我们要替换的错误,才处理    

  

   if (anErrorMessage.startsWith("the request was rejected because its size")) {    

  

     Matcher m = Pattern.compile("//d+").matcher(anErrorMessage);    

  

    String s1 = "";    

  

    if (m.find())   s1 = m.group();    

  

    String s2 = "";    

  

    if (m.find())   s2 = m.group();    

  

    //偷梁换柱,将信息替换掉    

     super.addActionError("你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");    

    //也可以改为在Field级别的错误  

    // super.addFieldError("file","你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");    

  

  } else {//否则按原来的方法处理   

  

     super.addActionError(anErrorMessage);    

}    

  

}   

 

这时这页面增加

 

[c-sharp] view
plaincopy

<s:fielderror/>  

就可以了。

 

做到这里还有个问题,就是原来页面上输入的其他文本内容也都不见了,也就是说params注入失败。

这个是没办法的,因为这个异常是在文件上传之前捕获的,文件未上传,同时params也为注入,所以这时最好重定向到一个jsp文件,提示上传失败,然后重写填写相应信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: