背景:在以前经常使用jspSmartUpload来进行文件上传的处理,里面的File类有getSize()方法可以很灵活的限制文件大小,倒是不怎么留意上传文件大小的控制,但是用 Struts写上传照片时本来好好的然后随便选上传了一张用相机拍的照片(比较大,20MB左右,平时测试都是随便找张截图)时懵逼了,提交上传后跳到Error页去了,控制台一串异常提示,相信这个问题很多人都已经遇到过也解决了,但是在这里我还是自己记下来加深理解.
主要异常提示
20:14:32,547 WARN [http-apr-8080-exec-6] MultiPartRequest:60 - Unable to parse request
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (11130896) exceeds the configured maximum (2097152)
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:797)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:323)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:341)
...... 下面省略 ......
分析原因: 错误日志很清楚的显示,请求被拒绝,因为大小超过了配置的大小,既然知道了错误原因,那么就开始解决问题.
解决问题: 既然是配置的大小太小,那么肯定就是可以配置的,寻找配置文件在哪里,最终我在struts2-core-2.2.1.jar包中的org\apache\struts2\default.properties中找到了struts.multipart.maxSize=2097152这一行配置信息,1024*1024*2=2097152说明Struts2的默认大小只有2MB,对于现在手机拍张照片动辄10MB的时代显然是不够的.
那么开始手动这个值:
我现在想把文件上传大小设置为30MB也就是1024*1024*3=3145728
因为我不用struts.properties,所以使用struts.xml来配置
在struts.xml文件中增加一行:
<constant name="struts.multipart.maxSize" value="3145728"/>
这样就配置了一个全局的上传大小限制值覆盖了default.properties中的默认值,但是我还想精确配置某个页面某个Action的大小限制,还需要在不同的package中配置拦截器;
注:package中配置的不能超过struts.multipart.maxSize的大小;
在对应的package中配置示例:
第一种配置方式:defaultStack在前面,超出fileUpload限定值的会报错但是还会进入Action继续执行.并且不超过struts.multipart.maxSize配置值的可以正常上传,也就是说fileUpload实际是不起效的.
<!-- 默认拦截器,默认拦截器在前面,超出maximumSize会继续执行进入Action,但控制台报错 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="fileUpload">
<param name="maximumSize">20971520</param>
</interceptor-ref>
第二种配置方式:defaultStack在fileUpload后面,如果上传文件超出的fileUpload中配置的大小,程序会报错,并且不会进入Action继续执行,也就是说被拦截时是没有进入Action的,直接就会跳到Error页面(前提是配置了Error);
<interceptor-ref name="fileUpload">
<param name="maximumSize">20971520</param>
</interceptor-ref>
<!-- 默认拦截器在后面,超出大小会报错,并且不进入Action -->
<interceptor-ref name="defaultStack"></interceptor-ref>
注意这种情况:如果没有配置defaultStack,会导致数据丢失,无法正常执行程序;
<interceptor-ref name="fileUpload">
<param name="maximumSize">20971520</param>
</interceptor-ref>
详细Demo:
......头文件省略......
<!-- 全局大小限制,必须 -->
<constant name="struts.multipart.maxSize" value="52428800"/>
<package name="testpackage" namespace="/" extends="struts-default">
<action name="Test_*" class="com.ssh.action.TestAction" method="{1}">
<result name="test">result.jsp</result>
<!-- 默认拦截器,默认拦截器在前面,超出maximumSize会继续执行进入Action,但控制台报错 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="fileUpload">
<param name="maximumSize">20971520</param>
</interceptor-ref>
</action>
</package>
以上,愚见;