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文件,提示上传失败,然后重写填写相应信息。
原因是上传文件过大,需要设置上传文件大小
在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文件,提示上传失败,然后重写填写相应信息。
相关文章推荐
- (Clob的写入和读取-java)更新数据库报错:SQL Error: 1461, SQLState: 72000 ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
- Eclipse 右键 Open declaration 出错
- JAVA的异常处理
- Java中Dialog对话框
- (java)处理socket通信过程中粘包的情况
- rxjava(二)Single与Subject
- Java compiler level does not match the version of the installed Java project facet.
- 仿googleMVP设计模式示例demo,结合rxjava,retrofit2.0
- Java 并发工具包 java.util.concurrent 用户指南
- 【转载】JAVA知识点(中)
- 【转载】JAVA知识点(上)
- java中关于拓展赋值运算符的注意事项!!
- Java IO操作——字节-字符转换流(OutputStreamWriter、InputStreamReader)
- 利用Spring的AbstractRoutingDataSource解决多数据源的问题
- java面向对象之多态
- Java ByteArrayOutputStream中buf 的大小增长问题
- SpringMVC学习笔记
- ThreadPoolExecutor源码解析(基于Java1.8)
- Rxjava+数据库?来用用SqlBrite和SqlDelight吧!
- springMvc 4.0 jackson包改变