CommonsMultipartResolver 和 HandlerExceptionResolver 工作不一致

CommonsMultipartResolver and HandlerExceptionResolver working inconsistently

我正在尝试使用 Spring 和 CommonsMultipartResolver 创建一个用于上传文件的简单表单。

我正在使用 Spring 4.0.6.RELEASE 和 Tomcat v7.0.57。我已将这些 Apache 依赖项添加到我的 pom 文件中:

        <!-- Apache Commons FileUpload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <!-- Apache Commons IO -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

我的 spring xml 文件中有以下配置:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5120000" />
</bean>

并且我已将以下方法添加到我的控制器中:

@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse httpServletResponse, Object o, Exception e) {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("website/upload");
    if (e instanceof MaxUploadSizeExceededException)
    {
        modelAndView.addObject("errors", "Maximum upload size of " + (((MaxUploadSizeExceededException) e).getMaxUploadSize() + " bytes exceeded"));
    }
    else
    {
        modelAndView.addObject("errors", "An unexpected error occurred.  Please try again later.");
    }

    return modelAndView;
}

如果我将 maxUploadSize 设置为较小的值(即 1mb)并上传稍大的文件(我使用 1.7mb 的文件进行测试),这会正常工作并且显示的页面会向用户显示错误。但是,对于 5MB 的更大限制,如果我上传的文件只比限制大几个字节,我的 resolveException 方法会被多次调用,但页面不会加载。我使用 Chrome 和 Firefox 进行了测试。在 Firefox 中,我收到一条错误消息 "The connection was reset"。在网络选项卡中,它表示 POST 是 "Aborted"。在 Chrome 中,我收到一条错误消息 "This webpage is not available",错误代码:ERR_CONNECTION_RESET。在网络选项卡中,POST 只是说它 "failed".

我的猜测是,对于较大的文件上传,它会在完成之前取消文件上传,这是我想保留的行为。但是,在这些情况下,我仍然想向用户展示一个更好的错误。

我尝试将 CommonsMultipartResolver 的 maxInMemorySize 属性增加到 10mb,但这似乎没有任何效果。谁能帮我弄清楚哪里出错了?

终于找到问题了。它实际上与 HandlerExceptionResolver 无关,似乎是由于我使用的 Tomcat 版本 (7.0.57) 中的设置所致。在 server.xml 中,我必须在连接器上指定 "maxSwallowSize" 属性。

根据 Tomcat 文档,maxSwallowSize 是 "The maximum number of request body bytes (excluding transfer encoding overhead) that will be swallowed by Tomcat for an aborted upload. An aborted upload is when Tomcat knows that the request body is going to be ignored but the client still sends it. If Tomcat does not swallow the body the client is unlikely to see the response. If not specified the default of 2097152 (2 megabytes) will be used. A value of less than zero indicates that no limit should be enforced."

http://tomcat.apache.org/tomcat-7.0-doc/config/http.html