Fra*_*ery 5 java servlets jetty
这是我部署到Jetty的servlet的代码:
public class StreamServlet extends HttpServlet
{
public void doGet( HttpServletRequest request,
HttpServletResponse response ) throws ServletException, IOException
{
response.setContentType( "text/xml; charset=UTF-8" );
response.setCharacterEncoding( "UTF-8" );
InputStream is = this.getServletContext().getResourceAsStream( "A.xml" );
BufferedReader reader = new BufferedReader(
new InputStreamReader( is, Charset.forName("UTF-8") ) );
String line = "";
try
{
while( (line = reader.readLine()) != null ) {
getServletContext().log( line );
writer.println( line );
writer.flush();
Thread.sleep( 1500 ); // for testing
}
}
catch (InterruptedException e)
{
getServletContext().log("exception",e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我在命令行上运行
curl -i http://localhost:8080/foo/servlet
Run Code Online (Sandbox Code Playgroud)
该文件A.xml包含大约13,000行; 所以curl正确显示1.5秒后收到的每一行.然后我打断了卷曲,但令我惊讶的是,servlet继续运行; 即在这个while循环中.
while( (line = reader.readLine()) != null ) {
getServletContext().log( line );
writer.println( line );
writer.flush();
Thread.sleep( 1500 ); // for testing
}
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种行为?我没有使用延续.我正在运行Jetty 6.1.26.我想要的是:当servlet线程检测到客户端已终止http连接时,它应该停止.
我不知道你从哪里得到 writer,所以我假设它来自 response.getWriter()。
我认为可能发生的情况是 Jetty 在将响应发送到客户端之前在内部缓冲响应。它需要这样做是因为它需要计算响应的大小,以便它可以在 HTTP 响应标头中设置“Content-Length”字段。这是客户端需要的,这样它就知道要读多少内容。(嗯,这并不是真正需要的,但这是另一个讨论。)
我认为 Jetty 实际上不会发送数据,直到您关闭 writer。我还认为flush()不会做任何事情,因为它无法发送任何数据,直到它知道没有更多数据即将到来。当您写入此缓冲流时,它不会检查连接是否仍然处于活动状态。
在你的循环中尝试这个:
for(String line = reader.readLine(); line != null && !writer.checkError(); line = reader.readLine()) {
getServletContext().log( line );
writer.println( line );
writer.flush();
Thread.sleep( 1500 ); // for testing
}
Run Code Online (Sandbox Code Playgroud)
我在想 writer.checkError() 可能会传播到实际的套接字输出流并检查它是否仍然打开。
编辑1:嗯,没关系,我错过了你说的flush()正在向curl发送数据的部分。不过,请在循环中尝试 checkError() 并让我知道这是否有效。
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |