2013-04-05 52 views
1

我有一個Java HttpServlet。這個servlet包含一組使用觀察者模式的對象,以便通過servlet的Response對象返回數據。這是我的doGet()方法中的HttpServlet的一個簡化的版本:Java Servlet - Observer模式導致null響應對象

protected void doGet(final HttpServletRequest request, final HttpServletResponse response) 
    MyProcess process = new MyProcess(); 
    // This following method spawns a few threads, so I use a listener to receive a completion event. 
    process.performAsynchronousMethod(request, new MyListener() { 
     public void processComplete(data) { 
      response.getWriter().print(data.toString()); 
     } 
    } 
} 

如示例所示,我有執行一種方法,該產生一個各種線程的,以便產生一個最終的數據集。此過程可能需要幾秒到一分鐘的時間。我的問題是,看起來,隨着doGet()方法完成,響應對象變爲空。當調用processComplete()時,響應對象將爲空 - 從而阻止我寫出任何數據。

只要調用異步方法,servlet就會關閉連接。

當使用觀察者模式進行異步任務時,是否有更好的方式來實現這種類型的servlet?我應該以另一種方式來做這件事嗎?

回答

3

當doGet方法終止時,servlet響應將被髮送回客戶端,它不會等待異步調用完成。您需要找到阻止所有異步任務完成的方法,然後才允許doGet()方法返回。

this question的答案應該指向正確的方向。

還有一點需要注意的是,您不能保證線程將會以串行方式寫入響應寫入器,您可能會發現各種打印操作會重疊並且輸出會出現亂碼(這可能對您無關緊要,取決於數據是什麼以及如何使用)

+0

這對我有效。謝謝!我只是將latch作爲參數傳遞給performInynchronousMethod()和countDown。 – 2013-04-05 13:11:11

1

您可以嘗試在spec version 3.0中使用異步servlet,但並非所有的web服務器都支持它,只能使用一些現代的servlet。但這意味着服務器將在這段時間內保持套接字連接。所以,你應該知道可以同時連接多少個客戶端,並不是所有的硬件/操作系統都能處理大量的開放連接。

而Web客戶端將等待,並可能有一個超時。您還應該考慮套接字連接可能斷開並且客戶端永遠無法獲得結果的情況(例如,某些代理服務器會中斷長時間運行的連接)。所以你應該允許「恢復」操作。

+0

我不認爲這是我的選擇,與我目前的網絡服務器。如果它支持它,我肯定會考慮這個選項。這似乎是一種更優雅的做事方式,而不是持有閂鎖。謝謝! – 2013-04-05 13:13:04