如何从SimpleMappingExceptionResolver中排除ClientAbortException

13
我正在使用SimpleMappingExceptionResolver将所有异常发送到一个视图,以便它们可以被很好地呈现。这个方法有效,但有一个例外情况:如果用户请求页面,然后发送“中止”���我不知道它是如何工作的,但我注意到如果我快速点击HTTP post表单提交按钮,Firefox 7会通知服务器它不再对结果感兴趣),那么当尝试呈现页面或以任何方式编写http响应时,Tomcat 6会引发ClientAbortException
现在开始出现问题了:SimpleMappingExceptionResolver“捕获”异常并尝试将其“优美地”呈现为html页面。这导致流已关闭异常,这会污染日志文件。(java.lang.IllegalStateException: getOutputStream() has already been called for this response)
迄今为止,我的做法是为“ClientAbortException”注册一个空的jsp页面。但我觉得这是一个hack。另一方面,我想这不是一个罕见的问题,因为我预计它几乎存在于渲染所有异常的每个spring应用程序中。那么,有没有人遇到过这个问题,或者有没有一个不那么hacky的解决方案的想法?
<bean
  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
  p:defaultErrorView="uncaughtException">
    <property name="exceptionMappings">
        <props>
           <prop key=".MissingServletRequestParameterException">
               resourceNotFound
           </prop>
           <prop key=".ClientAbortException">nothing</prop>
        </props>
     </property>
</bean>
3个回答

10

扩展SimpleMappingExceptionResolver,重写doResolveException()方法,在异常名称为ClientAbortExceptionresponse.isCommitted()返回null而不是返回super.doResolveException()


2

对于较新版本的Spring,您也可以使用@ExceptionHandler注释,可能与@ControllerAdvice(用于全局处理)一起使用。

@ControllerAdvice
public class GlobalDefaultExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(ClientAbortException.class)
    public void clientAbortExceptionHandler(HttpServletRequest request, ClientAbortException e) {
        // This usually means the browser closed or disconnected or
        // something. We can't do anything. To avoid excessive stack traces
        // in log, just print a simple message and return null
        String username = "<NONE>";
        Principal principal = request.getUserPrincipal();
        if (principal != null) {
            username = principal.getName();
        }
        logger.warn("ClientAbortException: username={},remoteAddr={},userAgent={},requestedURL={}", username,
                request.getRemoteAddr(), request.getHeader("User-Agent"), request.getRequestURL());
    }

}

1

在我看来,为不想处理的Exception注册nothing视图是一种优雅的方式,而不是hack的感觉;因为与其他异常相比,你甚至可以有多个不想呈现的异常。

我不建议为HandlerExceptionResolver提出自定义实现,因为这可能会增加可维护性成本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接