如果你的 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 新增)