如何从 SimpleMappingExceptionResolver 中排除 ClientAbortException

2022-09-04 21:29:32

我正在使用一个SimpleMappingExceptionResolver,它将所有异常发送到一个视图,在那里它被很好地呈现。除了一种情况之外,这有效:如果用户请求一个页面,然后发送并“中止”(我不知道它是如何工作的,但我注意到,如果我非常快速地点击HTTP post表单提交按钮,并且Firefox 7经常以某种方式通知服务器它不再对结果感兴趣。然后,当一个人尝试呈现页面或以任何类型的http响应时,Tomcat 6会上升一个ClientAbortException

现在开始麻烦了:“捕获”异常并尝试将其很好地呈现到html页面。然后,这会导致流已关闭异常,从而污染日志文件。(SimpleMappingExceptionResolverjava.lang.IllegalStateException: getOutputStream() has already been called for this response)

我所做的是,为“ClientAbortException”注册一个空的jsp页面。但我觉得这是一个黑客。另一方面,我想这不是一个不那么不常见的问题,因为我几乎在每个春季应用程序中都会呈现所有异常。那么,有没有人对这个问题有经验,或者对一个不那么棘手的解决方案有想法?

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

答案 1

扩展 ,重写方法,如果异常名称为 和 返回而不是返回 。SimpleMappingExceptionResolverdoResolveException()ClientAbortExceptionresponse.isCommitted()nullsuper.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());
    }

}

推荐