天天看點

[Java EE 7] Servlet 協定更新處理

HTTP 1.1 ([url=http://www.ietf.org/rfc/rfc2616.txt]RFC 2616[/url])14.42 節定義了 HTTP 更新機制,允許你從 HTTP 1.1 過渡到其它相容的協定。應用層的通信完全取決于更新後選擇的協定。用戶端和服務端完成協定更新後,後續請求都将使用新協定。典型的例子是如何将 HTTP 協定更新到 WebSocket,這在 [url=http://tools.ietf.org/html/rfc6455]RFC 6455[/url] 的 [url=http://tools.ietf.org/html/rfc6455#section-1.3]Opening Handshake[/url] 中有介紹。

Servlet 容器提供了協定更新機制,但容器本身沒有包含關于新協定的輔助類,新協定處理都封裝到 HttpUpgradeHandler 接口中進行。Servlet 容器和 HttpUpgradeHandler 之間的資料讀寫是通過位元組流。

下面的例子中,在 Servlet.service 方法中決定是否更新協定,并使用到了一個新的方法:HttpServletRequest.upgrade,還有兩個新的接口:javax.servlet.http.HttpUpgradeHandler 和 javax.servlet.http.WebConnection:

if (request.getHeader("Upgrade").equals("echo")) {
    response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
    response.setHeader("Connection", "Upgrade");
    response.setHeader("Upgrade", "echo");
    request.upgrade(MyProtocolHandler.class);
    System.out.println("Request upgraded to MyProtocolHandler");
}
           

請求中判斷了 Upgrade 頭資訊,用于判斷是否需要進行協定更新。如果 Upgrade 的值是 echo,那麼将會設定正确的響應 status 和頭資訊。request.upgrade 方法将會傳入 HttpUpgradeHandler 接口實作 Class 類。

當請求離開 service 方法之後,servlet 容器處理完了所有的 filter,然後标記目前請求需要由 HttpUpgradeHandler 的執行個體處理。

public class MyProtocolHandler implements HttpUpgradeHandler {
     @Override
     public void init(WebConnection wc) {
         //. . .
     }

    @Override
     public void destroy() {
         //. . .
     }
 }
           

上面的代碼是 HttpUpgradeHandler 接口的一個實作樣例。Servlet 将調用 HttpUpgradeHandler 的 init 方法,并傳入 WebConnection 對象,使 HttpUpgradeHandler 能通路到資料,當更新過程完成後,HttpUpgradeHandler.destroy 方法将會被調用。

文章來源:[url]http://www.aptusource.org/2014/04/java-ee-upgrade-processing/[/url]