如何在Spring-MVC中处理ClientAbortException?

时间:2016-02-17 08:18:59

标签: java spring spring-mvc

每当客户端中止连接时,我都会按如下方式记录ClientAbortException

org.apache.catalina.connector.ClientAbortException: java.io.IOException: APR error: -730053
    at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:353) ~[catalina.jar:8.0.26]
    at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:317) ~[catalina.jar:8.0.26]
    at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:110) ~[catalina.jar:8.0.26]
    at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1022) ~[jackson-core-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:891) ~[jackson-databind-2.6.5.jar:2.6.5]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:264) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

问题:因为我不关心客户端是否中断连接,我想要阻止日志记录。或者,阻止我的应用程序尝试实际返回响应。

我怎么能这样做?

我是否可以创建某种全局@ExceptionHandler(ClientAbortException.class),但如果我发现任何内容,则会返回void

2 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,我无法用Spring MVC和Exception处理程序做你所说的。 Spring MVC处理程序不会讨论一些例外(我猜是未经检查的)。我所做的是在web.xml中定义通用过滤器

  <!-- Filter for exception handling, for those exceptions don't catched by Spring MVC -->
  <filter>
    <filter-name>LoggerFilter</filter-name>
    <filter-class>com.myproject.commons.filters.ExceptionLoggerServletFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>LoggerFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

我的过滤器的来源:

public class ExceptionLoggerServletFilter implements Filter {
  private static Log log = LogFactory.getLog(ExceptionLoggerServletFilter.class);

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
      ServletException {
    try {
      chain.doFilter(request, response);
    } catch (Throwable e) {
      StringBuilder sb = new StringBuilder();
      sb.append("Exception detected in ExceptionLoggerServletFilter:");
      if (e instanceof org.apache.catalina.connector.ClientAbortException) {
        // don't do full log of this error
        sb.append(" ClientAbortException");
        log.error(sb.toString());
      } else {
        log.error(sb.toString(), e);
      }
      throw e;
    }
  }

  @Override
  public void destroy() {
  }

}

答案 1 :(得分:3)

至少从 Spring Boot 2.3.4(可能更早)开始,您可以通过以下方法使用带 from datetime import date from dateutil.relativedelta import relativedelta # Let's say the data was taken on 15 October 2020: refdate = date(2020, 10, 15) # The data itself: triplets of years, months, days as collected on 15 October 2020: data = [ [20, 2, 1], [53, 5, 10], ] # Extend the data with the birthdate: for person in data: person.append(refdate - relativedelta(years=person[0], months=person[1], days=person[2])) # Print the data: for person in data: print("{} years, {} months, {} days: born on {}".format(*person)) 注释的类:

@ControllerAdvice