Struts2 [Error]:multipart.JakartaMultiPartRequest:68 - Request exceeded size limit!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kiss_xiaojie/article/details/77899828

Struts2 [Error]:multipart.JakartaMultiPartRequest:68 - Request exceeded size limit!

struts2 版本:struts2.3.20


  • 错误信息

multipart.JakartaMultiPartRequest:68 - Request exceeded size limit!

org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (1418624662) exceeds the configured maximum (20971520)

  • 问题剖析

    • 从错误信息,可以很清楚的看出:问题的根源是上传文件过大。

    • 背景:使用 Struts2 上传文件

      • 下面为对应的部分 jsp 代码

          <form action="..."/>" method="post" enctype="multipart/form-data">
              <table>
              <td>
                  <input type="file" name="upload"/>
              </td>
              <td>
                  <input type="submit" value="提交">
              </td>
              </table>
          </form>
        
      • 下面为部分 struts.xml 配置

          <action name="linkMan_*" class="linkManAction" method="{1}">
              <result name="addLinkMan" type="dispatcher">/index.jsp</result>
              <result name="addSuccess" type="dispatcher">/index.jsp</result>
              <result name="input" type="redirect">/index.jsp</result>
          </action>
        
      • 下面是对应的 LinkManAction.java 类中上传文件的配置

          //上传文件
          private File upload;
          //上传文件名
          private String uploadFileName;
          //省略了 set get 方法
          ...
          //保存代码
          File file = new File("E:\\CRM\\" + uploadFileName);
          FileUtils.copyFile(upload, file);
        
    • 剖析

      • struts2 中默认可上传最大为 2MB 的文件。当然,这可满足我们大部分需要,而就算有更大的文件需能上传,我们也可以通过以下全局配置来扩展。

          <!-- 配置上传文件允许的最大大小 -->
          <constant name="struts.multipart.maxSize" value="20971520"/>
        
      • 可是,再大也有尽头。如果用户不小心上传了一个很大的文件,我们该怎么办?

        • 不得不说 struts2 很棒!若遇到上传的文件比设置的最大可接受值大时,它会抛出最上面的异常。并且,正常的话 还会返回 input 以方便我们可以跳转到错误页面友好地提醒用户。请注意我说的是正常的话,如果一切都是正常的我就不会写这博客了。。。
        • 从上面的 struts.xml 中可以很清楚的看到我已经设置了 input 对应的 result。然而,我上传一个大文件进行测试的时,最后浏览器每次都显示连接中断。。。这不科学啊!我的友好提示呢!
    • 调试

      • 1)是不是地址写错
        • 于是我上传了一个小文件,结果很正常。我在服务器里面找到了上传的文件。
        • 我便排除了这种可能。
      • 2)难道并不返回 input
        • 于是,我尝试去掉 struts2.xml 中的关于 inputresult 配置,然后跑一下。当我测试上传一个大文件时,除了最上面的异常,还抛出了:

            No result defined for action action.LinkManAction and result input - action - file:/D:/project/CRM/out/artifacts/SSH_war_exploded/WEB-INF/classes/struts.xml:40:69
          
        • 这分明是提示我没写 input 对应的 result 。可是,我配置了后为嘛又不跳转呢(上面我分明写上了)。我不死心,又把它加上了,可结果一样:浏览器依然以连接中断结束。

        • 这 TM 到底怎么了!!!

      • 3)于是我开始 Google巨大发现。。。
        • Struts2 高危漏洞 (CVE-2017-5638) 点我
        • 不会吧,我就随便练习一下 struts2 ,居然让我碰到高危漏洞了。
        • 放弃了,不弄了,估计就是那漏洞的问题了,现已累成狗~~~
      • 4)这心态不对!问题总是要解决的!唉,肯定不是漏洞的问题。理性分析一波(偷笑,小胖子)
        • 开启调试模式!给默认的拦截器 StrutsPrepareAndExecuteFilter 打上断点,我看看它究竟是在哪里抛出的异常!

        • 我发现,这货居然没等到 FileUploadInterceptor 就结束了。FileUploadInterceptor 可是正宗的处理文件上传的拦截器啊!

        • 没想到,在进入 FileUploadInterceptor 之前,还有 FileUploadBase 验身,它发现文件过大时就会抛出上述异常。且按照正常的说,还会返回 input

        • 新的解决方案:既然你能抛出异常,我如下设置不就行了嘛

            <global-results>
                <result name="error">/index.jsp</result>
            </global-results>
            <global-exception-mappings>
                <exception-mapping exception="org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException" result="error"/>
            </global-exception-mappings>
          
        • 结果还是那样,不起作用啊!MMP!到底哪里错了!是谁吞了 input ?

        1. 新思路
        • 我惹不起,还躲不起吗?

        • 我把你配置为最大值 (struts.multipart.maxSize 要求 value 是一个 int)

            <!-- 配置上传文件允许的最大大小 -->
            <constant name="struts.multipart.maxSize" value="2147483647"/>
          
        • 这样 FileUploadBase 就没有理由拦下来了。于是,可以顺畅的进入 FileUploadInterceptor

        • 因为 FileUploadInterceptor 是正宗的文件上传拦截器,所有也可以设置允许的上传文件大小

            <interceptor-ref name="fileUpload">
                <param name="maximumSize">2097152</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack" />
          
        • 果然成功了!那个 input 居然返回来了,于是 input 对应的 result 起来作用!(爽~~~然而,让我绕了这么大弯子!)

        • 这样,在用户不小心上传超大文件时,我们就可以进行友好提示了!

  • 最终还是有疑问

    • 那个 input 到底去哪里了?为什么不写 input 对应的 result 时会有警告,而写上有不起作用了?到底哪里错了?真的与 struts2 漏洞有关(几率很小),还是一个新 struts2bug
    • 虽然有了解决方案,但是还有好多疑问,以后读源码时一定要解决!!!

猜你喜欢

转载自blog.csdn.net/kiss_xiaojie/article/details/77899828