Linux安全网 - Linux操作系统_Linux 命令_Linux教程_Linux黑客

绿色网站无广告
会员投稿 投稿指南 本期推荐:
搜索:
您的位置: Linux安全网 > Linux集群 > Architecture > » 正文

浅谈对struts2.2 the request was rejected because its siz

来源: wanxiaotao12 分享至:

最近在学struts2 ,在上传文件时发现有个异常不好处理,经过google终于有点小眉目,现浅谈下这个异常处理。有不妥当的地方还请指教

在struts2中我们上传文件大于struts.multipart.maxSize设置的值时会抛出the request was rejected because its size (XXXX) exceeds the configured maximum (XXXX)异常,他是不能被国际化的,这信息对应用户来说是非常不友好的,那任何处理?

 

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

一个是在拦截器fileUpload中设置

 

view plain

  1. <interceptor-ref name="fileUpload">
  2. <param name="maximumSize">1000000</param>
  3. </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 中我们看到

 

view plain

  1. /**
  2. * Creates a new instance.
  3. * @param ctx The request context.
  4. * @throws FileUploadException An error occurred while
  5. * parsing the request.
  6. * @throws IOException An I/O error occurred.
  7. */
  8. FileItemIteratorImpl(RequestContext ctx)
  9. throws FileUploadException, IOException {
  10. if (ctx == null) {
  11. throw new NullPointerException("ctx parameter");
  12. }
  13.  
  14. String contentType = ctx.getContentType();
  15. if ((null == contentType)
  16. || (!contentType.toLowerCase().startsWith(MULTIPART))) {
  17. throw new InvalidContentTypeException(
  18. "the request doesn't contain a "
  19. + MULTIPART_FORM_DATA
  20. + " or "
  21. + MULTIPART_MIXED
  22. + " stream, content type header is "
  23. + contentType);
  24. }
  25.  
  26. InputStream input = ctx.getInputStream();
  27.  
  28. if (sizeMax >= 0) {
  29. int requestSize = ctx.getContentLength();
  30. if (requestSize == -1) {
  31. input = new LimitedInputStream(input, sizeMax) {
  32. protected void raiseError(long pSizeMax, long pCount)
  33. throws IOException {
  34. FileUploadException ex =
  35. new SizeLimitExceededException(
  36. "the request was rejected because"
  37. + " its size (" + pCount
  38. + ") exceeds the configured maximum"
  39. + " (" + pSizeMax + ")",
  40. pCount, pSizeMax);
  41. throw new FileUploadIOException(ex);
  42. }
  43. };
  44. } else {
  45. ///问题就在这里////////////////////////////////////
  46. if (sizeMax >= 0 && requestSize > sizeMax) {
  47. throw new SizeLimitExceededException(
  48. "the request was rejected because its size ("
  49. + requestSize
  50. + ") exceeds the configured maximum ("
  51. + sizeMax + ")",
  52. requestSize, sizeMax);
  53. }
  54. }
  55. }
  56.  
  57. String charEncoding = headerEncoding;
  58. if (charEncoding == null) {
  59. charEncoding = ctx.getCharacterEncoding();
  60. }
  61.  
  62. boundary = getBoundary(contentType);
  63. if (boundary == null) {
  64. throw new FileUploadException(
  65. "the request was rejected because "
  66. + "no multipart boundary was found");
  67. }
  68.  
  69. notifier = new MultipartStream.ProgressNotifier(listener,
  70. ctx.getContentLength());
  71. multi = new MultipartStream(input, boundary, notifier);
  72. multi.setHeaderEncoding(charEncoding);
  73.  
  74. skipPreamble = true;
  75. findNextItem();
  76. }

 

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

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

 

 

view plain

  1. /**
  2.  
  3. * 替换文件上传中出现的错误信息
  4. *引用 import java.util.regex.Matcher;
  5. * import java.util.regex.Pattern;
  6. *
  7. * */
  8.  
  9. @Override
  10.  
  11. public void addActionError(String anErrorMessage) {
  12.  
  13. //这里要先判断一下,是我们要替换的错误,才处理
  14.  
  15. if (anErrorMessage.startsWith("the request was rejected because its size")) {
  16.  
  17. Matcher m = Pattern.compile("//d+").matcher(anErrorMessage);
  18.  
  19. String s1 = "";
  20.  
  21. if (m.find()) s1 = m.group();
  22.  
  23. String s2 = "";
  24.  
  25. if (m.find()) s2 = m.group();
  26.  
  27. //偷梁换柱,将信息替换掉
  28. super.addActionError("你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");
  29. //也可以改为在Field级别的错误
  30. // super.addFieldError("file","你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");
  31.  
  32. } else {//否则按原来的方法处理
  33.  
  34. super.addActionError(anErrorMessage);
  35. }
  36.  
  37. }

 

 

这时这页面增加

 

view plain

  1. <s:fielderror/>

 

就可以了。

 

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

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


Tags:
分享至:
最新图文资讯
1 2 3 4 5 6
验证码:点击我更换图片 理智评论文明上网,拒绝恶意谩骂 用户名:
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 发展历史