Java Async NIO servlet无法按预期工作

时间:2016-03-01 14:36:15

标签: java servlets asynchronous nio

我正在尝试使用一个简单的servlet(从另一个源复制)。它是一个异步servlet,通过ReadListener使用NIO读取post请求。这是代码:

@WebServlet(name = "AsyncProxyServlet2", urlPatterns = "/*" , asyncSupported = true)
public class AsyncProxyServlet2 extends HttpServlet 
{
 private static final long serialVersionUID = 8458401860448619054L;

 @Override
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException 
 {
  final AsyncContext acontext = request.startAsync();
  final ServletInputStream input = request.getInputStream();
  System.out.println("request.isAsyncStarted() = " + request.isAsyncStarted() + ", request.isAsyncSupported = " + request.isAsyncSupported() + ", main = " + Thread.currentThread().getName());  

  input.setReadListener(new ReadListener()
  {
   byte tmp[] = new byte[4*1024];
   ByteArrayOutputStream buffer     = new ByteArrayOutputStream(this.tmp.length);

   @Override
   public void onDataAvailable() 
   {
    try 
    {
     System.out.println("onDataAvailable = " + Thread.currentThread().getName());    
     int numBytesRead = -1;

     while ( input.isReady() && !input.isFinished() )
     {
      if ( (numBytesRead = input.read(this.tmp)) > 0 ) this.buffer.write(this.tmp, 0, numBytesRead);
     }
    } 
    catch (IOException ex) { ex.printStackTrace(); }
   }

   @Override
   public void onAllDataRead() 
   {
    try 
    {
     System.out.println("onAllDataRead = " + Thread.currentThread().getName() + ", buffer size = " + this.buffer.size());    

     acontext.getResponse().setContentType("text/xml; charset=utf-8");
     acontext.getResponse().setContentLength(this.buffer.size());
     acontext.getResponse().getOutputStream().write(this.buffer.toByteArray());
    } 
    catch (Exception ex) { ex.printStackTrace(); }

    acontext.complete();
   }

   @Override
   public void onError(Throwable t) { t.printStackTrace(); }
  });

  System.out.println("final 1");
  try { Thread.sleep(3000); } catch (Exception e) {}
  System.out.println("final 2");
 }

}

当我向此servlet发送post请求时,此代码的输出为:

request.isAsyncStarted() = true, request.isAsyncSupported = true, main = http-nio-80-exec-1
final 1
<-- Here a 3 second pause
final 2
onDataAvailable = http-nio-80-exec-1
onAllDataRead = http-nio-80-exec-1, buffer size = 910

所以似乎一切都在同一个线程上执行。直到3秒暂停结束才会读取请求,然后打印最后3条消息。

为什么这不能正常工作?

1 个答案:

答案 0 :(得分:0)

暂停3秒......

try { Thread.sleep(3000); } catch (Exception e) {}

只需注释掉这一行。