如何处理仅限于ClientAbortException的异常?

3
我正在编写一个文件下载控制器,有时用户在文件完全写入之前会关闭浏览器窗口,这很好。
问题是我的日志中充满了这个错误:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:333) at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:758) at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:663) at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368) at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346) at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2147) at org.apache.commons.io.IOUtils.copy(IOUtils.java:2102) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2123) at org.apache.commons.io.IOUtils.copy(IOUtils.java:2078)
当我尝试仅捕获此特定错误时,eclipse会报错:
ClientAbortException无法解析为类型
我已经正确设置并运行了项目,那么是否可能仅捕获此特定异常呢?
   org.apache.catalina.connector.ClientAbortException

如果发生另一种灾难,我希望保留IOException。

try catch 结构


1
我强烈建议您包含能够轻松复制粘贴和再现的代码,而不是图片。或者保留图片以突出显示发生的情况,但请务必同时“包含”代码。 - Nikolas Charalambidis
1
你的代码是否正在运行(捕获ClientAbortException并且没有将其记录在日志中)?如果没有,为什么?这将有助于了解你需要什么样的帮助。 - Niklas P
3个回答

4

ClientAbortException是从IOException派生而来的。您必须检查导致IOException e的确切异常:

...
} catch (FileNotFoundException fnfe) {
    // ... handle FileNotFoundException
} catch (IOException e) {
    String exceptionSimpleName = e.getCause().getClass().getSimpleName();
    if ("ClientAbortException".equals(exceptionSimpleName)) {
        // ... handle ClientAbortException
    } else {
        // ... handle general IOException or another cause
    }
}
return null;

1
不是直接抛出异常,所以不能直接处理。您必须使用我所描述的方法。这能行吗? :)) - Nikolas Charalambidis

1
截至@Nikolas Charalambidis的回答。
  • Ignore "org.apache.catalina.connector.ClientAbortException:java.io.IOException: Connection reset by peer"

    e.getCause().getClass().getSimpleName() == "IOException"

    e.getMessage() == "java.io.IOException: Connection reset by peer"

  • And don't handle general IOException and another cause

     ...    
     } catch (IOException e) {
         if (! e.getMessage().contains("Connection reset by peer")) {
             throw e;
         }
    
     } finally {
         close(output);
         close(input);
     }
     ...
    

我不确定你说的“根据尼古拉斯的回答”的意思是什么。你是想在尼古拉斯的回答基础上增加一些额外的信息吗?单独看这个回答本身并不太清晰。也许可以考虑将你的要点重写为完整的句子。 - yegeniy

1

与其寻找特定的类名(将您的应用程序绑定到特定的servlet容器),我通常以不同的方式处理写入时的 IOExceptions 和读取时的 IOExceptions,就像这样(非常伪代码):

try {
  byte[] buffer = ...
  in.read(buffer);
  try {
    out.write(buffer);
  } catch (IOException writeException) {
    // client aborted request
  }
} catch (IOException readException) {
  // something went wrong -> signal 50x or something else
}

到目前为止,工作得相当不错。


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