更多 AsyncContext


如果你的 Servlet 或過濾器的 asyncSupported 被標示為 true,則它們支援非同步請求處理,在不支援非同步處理的 Servlet 或過濾器中呼叫 startAsync(),會丟出 IllegalStateException。

當你在支援非同步處理的 Servlet 或過濾器中呼叫請求物件的 startAsync() 方法時,該次請求會離開容器所分配的執行緒,這意謂著必須回應處理流程會返回,也就是若有過濾器,也會依序返回(也就是各自完成 FilterChain 的 doFilter() 方法),但最終的回應被延遲。

你可以呼叫 AsyncContext 的 complete() 方法完成回應,或是呼叫 forward() 方法,將回應轉發給別的 Servlet/JSP 處理,AsyncContext 的 forward() 就如同〈調派請求〉中所介紹的功能,將請求的回應權派送給別的頁面來處理,所給定的路徑是相對於 ServletContext 的路徑。

不可以自行在同一個 AsyncContext 上同時呼叫 complete() 與 forward(),這會丟出 IllegalStateException。

不可以在兩個非同步處理的 Servlet 間派送前,連續呼叫兩次 startAsync(),否則會丟出 IllegalStateException。

將請求從支援非同步處理的 Servlet(asyncSupported 被標示為 true)派送至一個同步處理的 Servlet 是可行的(asyncSupported 被標示為 false),此時,容器會負責呼叫 AsyncContext 的 complete()。

如果從一個同步處理的 Servlet 派送至一個支援非同步處理的 Servlet,在非同步處理的 Servlet 中呼叫 AsyncContext 的 startAsync() ,將會丟出 IllegalStateException。

如果你對 AsyncContext 的啟始、完成、逾時或錯誤發生等事件有興趣,可以實作 AsyncListener:

package javax.servlet;

import java.io.IOException;
import java.util.EventListener;

public interface AsyncListener extends EventListener {
    void onComplete(AsyncEvent event) throws IOException;
    void onTimeout(AsyncEvent event) throws IOException;
    void onError(AsyncEvent event) throws IOException;
    void onStartAsync(AsyncEvent event) throws IOException;
}

AsyncContext 有個 addListener() 方法,可以讓你加入 AsyncListener 的實作物件,在對應的事件發生時會呼叫 AsyncListener 實作物件的對應方法。

如果呼叫 AsyncContext 的 dispatch(),將請求調派給別 的Servlet,亦可以透過請求物件的 getAttribute() 取得以下的屬性,說明可以見〈URL 模式〉的內容:

  • AsyncContext.ASYNC_REQUEST_URI
  • AsyncContext.ASYNC_CONTEXT_PATH
  • AsyncContext.ASYNC_SERVLET_PATH
  • AsyncContext.ASYNC_PATH_INFO
  • AsyncContext.ASYNC_QUERY_STRING
  • AsyncContext.ASYNC_MAPPING(Servlet 4.0 新增)