Java 如何从SimpleMappingExceptionResolver中排除ClientBortException

Java 如何从SimpleMappingExceptionResolver中排除ClientBortException,java,spring,tomcat,exception-handling,Java,Spring,Tomcat,Exception Handling,我使用的是SimpleMappingExceptionResolver,它将所有异常发送到一个视图,并在该视图中进行良好渲染。除一种情况外,这一方法有效: 如果用户请求一个页面,然后发送并“中止”(我不知道具体是如何工作的,但我注意到如果我快速单击HTTP post表单提交按钮,Firefox 7通常会以某种方式通知服务器它不再对结果感兴趣。)然后,当试图呈现页面时,Tomcat 6会出现一个错误,或者以任何形式编写http响应 现在麻烦来了:SimpleMappingExceptionReso

我使用的是SimpleMappingExceptionResolver,它将所有异常发送到一个视图,并在该视图中进行良好渲染。除一种情况外,这一方法有效: 如果用户请求一个页面,然后发送并“中止”(我不知道具体是如何工作的,但我注意到如果我快速单击HTTP post表单提交按钮,Firefox 7通常会以某种方式通知服务器它不再对结果感兴趣。)然后,当试图呈现页面时,Tomcat 6会出现一个错误,或者以任何形式编写http响应

现在麻烦来了:
SimpleMappingExceptionResolver
“捕获”异常并尝试将其很好地呈现到html页面。然后,这会导致流中已关闭的异常污染日志文件。(
java.lang.IllegalStateException:已为此响应调用getOutputStream()

我所做的就是为“ClientBortException”注册一个空jsp页面。但我觉得这是一个黑客。另一方面,我想这并不是一个很不寻常的问题,因为我预计几乎在每个呈现所有异常的spring应用程序中都会遇到这个问题。那么,有没有人有过这个问题的经验,或者有没有一个不太老套的解决方案的想法

<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>

未找到资源
没有什么

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

异常注册
nothing
视图是一种优雅的方式;与黑客的感觉相反;由于您甚至可以有多个异常,与其他异常相比,您不想/不想呈现这些异常


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

对于较新版本的Spring,您还可以使用注释,可能使用(用于全局处理)

@ControllerAdvice
公共类GlobalDefaultExceptionHandler{
私有最终记录器Logger=LoggerFactory.getLogger(getClass());
@ExceptionHandler(ClientAbortException.class)
public void clientAbortExceptionHandler(HttpServletRequest请求,ClientAbortException e){
//这通常意味着浏览器关闭或断开连接,或
//有些东西。我们什么都做不了。为了避免过多的堆栈跟踪
//在日志中,只需打印一条简单消息并返回null
字符串username=“”;
Principal=request.getUserPrincipal();
if(主体!=null){
username=principal.getName();
}
warn(“ClientAbortException:username={},remoteAddr={},userAgent={},requestedURL={}”,username,
request.getRemoteAddr()、request.getHeader(“用户代理”)、request.getRequestURL();
}
}
@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());
    }

}