Removing Content-Disposition causes ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer
Removing Content-Disposition causes ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer
我的应用程序服务器 .wav 文件,可从某些 URL 下载。我必须更改逻辑,以便将它们流式传输而不是下载 - 所以我将删除明确设置的 Content-Disposition header。
一段代码:
// removed
//response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
bis = new BufferedInputStream(inputStream);
bos = new BufferedOutputStream(sOutputStream);
byte[] buff = new byte[10000];
int bytesRead = 0;
while(-1 != (bytesRead = bis.read(buff))) {
bos.write(buff, 0, bytesRead);
}
bos.flush();
第 2 次或第 3 次调用 bos.write
导致
ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:402)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:449)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:349)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:425)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:414)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
当我调试代码时,write 方法失败时,浏览器打开一个播放器,然后生成另一个相同的请求并成功。
设置 Content-Disposition 后一切正常。有什么想法吗?
这是因为客户端在注意到它实际上是一个媒体文件后中止了请求,并通过客户端的媒体播放器通过 HTTP Range
请求切换到流模式以提高缓冲速度。然后客户端将在文件的不同部分触发多个 HTTP 请求(显然,只有当您的 servlet 也真正支持它时,这才能有效地工作......许多本地文件 servlet 不支持并且最终可能会表现得更糟)。
至于服务器日志中的那些客户端中止异常,最好的办法是过滤掉并抑制它们,或者至少使用 DEBUG/INFO oneliner 而不是整个堆栈跟踪记录。
另请参阅:
- How to stream audio/video files such as MP3, MP4, AVI, etc using a Servlet
- ClientAbortException at application deployed at jboss with IE8 browser
我的应用程序服务器 .wav 文件,可从某些 URL 下载。我必须更改逻辑,以便将它们流式传输而不是下载 - 所以我将删除明确设置的 Content-Disposition header。
一段代码:
// removed
//response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
bis = new BufferedInputStream(inputStream);
bos = new BufferedOutputStream(sOutputStream);
byte[] buff = new byte[10000];
int bytesRead = 0;
while(-1 != (bytesRead = bis.read(buff))) {
bos.write(buff, 0, bytesRead);
}
bos.flush();
第 2 次或第 3 次调用 bos.write
导致
ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:402)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:449)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:349)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:425)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:414)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
当我调试代码时,write 方法失败时,浏览器打开一个播放器,然后生成另一个相同的请求并成功。
设置 Content-Disposition 后一切正常。有什么想法吗?
这是因为客户端在注意到它实际上是一个媒体文件后中止了请求,并通过客户端的媒体播放器通过 HTTP Range
请求切换到流模式以提高缓冲速度。然后客户端将在文件的不同部分触发多个 HTTP 请求(显然,只有当您的 servlet 也真正支持它时,这才能有效地工作......许多本地文件 servlet 不支持并且最终可能会表现得更糟)。
至于服务器日志中的那些客户端中止异常,最好的办法是过滤掉并抑制它们,或者至少使用 DEBUG/INFO oneliner 而不是整个堆栈跟踪记录。
另请参阅:
- How to stream audio/video files such as MP3, MP4, AVI, etc using a Servlet
- ClientAbortException at application deployed at jboss with IE8 browser