Jetty開發指導:Handlers

來源:互聯網
上載者:User

標籤:java   jetty   web應用   架構   

Rewrite Handler

RewriteHandler基於一套規則匹配一個請求,然後根據匹配的規則修改請求。最常見的是重寫請求的URI,但是不僅限於此:規則能被配置為重新導向響應、設定一個cookie或者響應的響應代碼、修改header,等等。

快速開始

標準Jetty發布中包含jetty-rewrite模組JAR,在lib/jetty-rewrite-*.jar,和一個例子設定檔,在etc/jetty-rewrite.xml。為了啟用重寫模組,用例子設定檔,用如下命令啟動Jetty:

$ java -jar start.jar OPTIONS=default,rewrite etc/jetty.xml etc/jetty-rewrite.xml 

注意:如果你正在使用例子test webapp運行標準Jetty發布,有一個重寫模組的demo在http://localhost:8080/rewrite/ 。

配置Rules

rules通過使用jetty.xml配置。下面的例子檔案展示怎麼為server增加重寫handler:

<Configure id="Server" class="org.eclipse.jetty.server.Server">    <!-- create and configure the rewrite handler -->    <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">      <Set name="rewriteRequestURI">true</Set>      <Set name="rewritePathInfo">false</Set>      <Set name="originalPathAttribute">requestedPath</Set>        <!-- redirect the response. This is a redirect which is visible to the browser.           After the redirect, the browser address bar will show /redirected -->      <Call name="addRule">        <Arg>          <New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">            <Set name="pattern">/redirect/*</Set>            <Set name="replacement">/redirected</Set>          </New>        </Arg>      </Call>        <!-- rewrite the request URI. This is an internal rewrite, visible to server,           but the browser will still show /some/old/context -->      <Call name="addRule">        <Arg>          <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">            <Set name="pattern">/some/old/context</Set>            <Set name="replacement">/some/new/context</Set>          </New>        </Arg>      </Call>        <!-- reverse the order of the path sections. Internal rewrite -->      <Call name="addRule">        <Arg>          <New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">            <Set name="regex">/reverse/([^/]*)/(.*)</Set>            <Set name="replacement">/reverse/$2/$1</Set>          </New>        </Arg>      </Call>    </New>       <!-- add the rewrite handler to the server -->    <Set name="handler"><Ref id="Rewrite" /></Set></Configure>

更多的配置例子請看etc/jetty-rewrite.xml。

嵌入的例子

下面是嵌入Jetty的一個例子,和上面的設定檔做同樣的事情:

Server server = new Server(); RewriteHandler rewrite = new RewriteHandler();rewrite.setRewriteRequestURI(true);rewrite.setRewritePathInfo(false);rewrite.originalPathAttribute("requestedPath"); RedirectPatternRule redirect = new RedirectPatternRule();redirect.setPattern("/redirect/*");redirect.setReplacement("/redirected");  rewrite.addRule(redirect); RewritePatternRule oldToNew = new RewritePatternRule();oldToNew.setPattern("/some/old/context");oldToNew.setReplacement("/some/new/context");rewrite.addRule(oldToNew); RewriteRegexRule reverse = new RewriteRegexRule();reverse.setRegex("/reverse/([^/]*)/(.*)");reverse.setReplacement("/reverse/$2/$1");rewrite.addRule(reverse); server.setHandler(rewrite);
Rules

有幾種不同類型的rules。

PatternRule

用servlet模式文法匹配請求的URI。

CookiePatternRule

增加一個cookie到響應。

HeaderPatternRule

增加/修改響應中的header。

RedirectPatternRule

重新導向響應。

ResponsePatternRule

發送響應碼(status或者error)。

RewritePatternRule

重寫URI。

RegexRule

用Regex匹配請求URI。

RedirectRegexRule

重新導向響應。

RewriteRegexRule

重寫URI

HeaderRule

匹配請求headers。匹配或者在一個header名稱+特定的值,或者在一個header的存在(加任何值)。

ForwardedSchemaHeaderRule

佈建要求的計劃(scheme)(預設是https)。

其它

其它較為古怪的規則。

MsieSslRule

對IE5和IE6禁用為SSL保持活躍。

LegacyRule

實現RewriteHandler的遺留API。

RuleContainer

將rules組織在一起。

VirtualHostRuleContainer

包含的rules僅應用到一個特定的虛擬機器主機或者一套虛擬機器主機。

寫自訂的handlers

handler是處理請求的Jetty組件。
一些Jetty使用者從不需要寫Jetty handler,而是使用Servlet API(http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/servlet/package-summary.html)。你能重用已經存在的Jetty handlers,為上下文、安全、sessions和servlets,不需要任何擴充。然而,一些使用者可能有特殊的需求或者擔心足跡問題而禁用完整的servlet API。為他們實現一個Jetty handler是一種直截了當的方法,用最小的改動提供動態web內容。

Handler API

Handler介面提供了Jetty內容產生和處理的核心。實現這個介面的類被用於協調請求、過濾請求和產生內容。
Handler介面的核心API是:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)    throws IOException, ServletException

這個方法的實現能處理一個請求、傳遞請求到另一個handler(或servlet)、或者它能修改和/或封裝請求,然後傳遞它。存在三種類型的handler:
 1)協調Handlers:傳遞請求到其它handlers(HandlerCollection、ContextHandlerCollection);
 2)過濾Handlers:放大一個請求,然後傳遞它到其它handlers(HandlerWrapper, ContextHandler, SessionHandler);
 3)產生Handlers:產生內容(ResourceHandler和ServletHandler)。

目標

一個handler的目標是處理請求的資源的標識符。這通常是來自一個HTTP請求的URI。然而,在下面兩種環境下目標可以不同於請求的URI:
 1)如果請求被分發到一個命令的資源,例如一個命名的servlet,目標是那個資源的名稱;
 2)如果請求是通過請求發送器,目標是包含的資源的URI,不同於真正請求的URI。

請求和響應

處理方法的簽名中使用的請求和響應對象是Servlet Request和Servlet Response。這些是標準的API。更經常的是,進入這些類的Jetty實現被要求:Request和Response。然而,由於請求和響應可以被handlers、filters和servlets封裝,直接地傳遞實現是不可能的。下面的方法用於擷取任何封裝器下的核心實現對象:

Request base_request = request instanceof Request ? (Request)request : HttpConnection.getCurrentConnection().getRequest();Response base_response = response instanceof Response ? (Response)response : HttpConnection.getCurrentConnection().getResponse();

注意如果handler傳遞請求到另一個handler,他應該用request/response對象傳遞,不使用基礎對象。這是為了保留被上遊handlers做的封裝。

分發

分發參數展示了調用處理的狀態,可以為:
 1)REQUEST == 1:從一個連接器收到的原始請求;
 2)FORWARD == 2:被一個RequestDispatcher前轉的請求;
 3)INCLUDE == 4:被一個RequestDispatcher包括的請求;
 4)ERROR == 8:被容器前轉到一個error handler的請求。
這些對大部分的servlet和相關的handlers都是有意思的。例如,安全handler僅對REQUEST分發應用認證和授權。

處理請求

一個Handler可以處理一個請求通過:
 1)產生一個響應;
 2)過濾請求和/或響應;
 3)傳遞請求和響應到另一個Handler。
下面具體講述。

產生一個響應

OneHandler展示了怎麼產生一個響應。

你能用通常的servlet響應API,通常將設定一些狀態、內容headers、然後輸出內容:

response.setContentType("text/html");response.setStatus(HttpServletResponse.SC_OK);response.getWriter().println("<h1>Hello OneHandler</h1>");

handler需要標註它完成了對請求的處理,請求不應該被傳遞到其它handlers了:

Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();base_request.setHandled(true);
過濾請求和/或響應

一旦基礎請求或響應對象被擷取,你就能修改它。一般你將做修改以完成:
 1)拆分URI到contextPath、servletPath和pathInfo組件;
 2)為靜態內容將請求和資源相關聯;
 3)將請求和session相關聯;
 4)將請求和安全性主體相關聯;
 5)在請求分發到另一個資源期間改變URI和路徑。
你也能更新要求的上下文:
 1)設定當前線程上下文類載入器;
 2)設定線程局部變數來表示當前ServletContext。
通常Jetty傳遞一個已修改的請求到另一個handler,並在finally塊只能夠還原修改:

try{   base_request.setSession(a_session);   next_handler.handle(target,request,response,dispatch);}finally{   base_request.setSession(old_session);}

實現HandlerWrapper類的類是典型的這種類型的handler過濾器。

傳遞請求和響應到另一個Handler

一個Handler可以簡單的視察請求,然後使用目標、請求URI或其它資訊以選擇另一個Handler作為下一個處理請求的Handler。這些handlers通常實現HandlerContainer介面。
例子包括:

Class Handler Collection

HandlerList

ContextHandlerCollection

更多Handlers的資訊

看Jetty Latest Source XRef和Jetty Latest JavaDoc擷取每一個Jetty Handler的詳細資料。

 

更多Jetty資料請看Jetty總覽。

Jetty開發指導:Handlers

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.