久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

servlet filter 詳解_Step-By-Step_百度空間

 JourneyHappy 2014-12-01
Servlet Filtering

過濾器(filter)是Java類,可以改變請求(request)和響應(response)的頭信息與內(nèi)容信息,。過濾器不同于其他Web組件的地方是它本身并不創(chuàng)建響應(response),,然而它可以依附在任何類型的Web資源上。過濾器截取請求(request),,檢查和改變request對象,、response對象,并可以執(zhí)行一些其他的任務,。過濾器提供的主要功能是:

  • 實現(xiàn)日志功能

  • 實現(xiàn)用戶定義的安全功能

  • 調(diào)試功能

  • 加密

  • 數(shù)據(jù)壓縮

  • 改變發(fā)送給客戶端的響應(response)

過濾器截獲對特定命名的一個資源和一組資源的請求(request),,然后執(zhí)行過濾器中的代碼。對于特定的資源,,可以指定按照一定順序調(diào)用的一個和多個過濾器,,這就組成了鏈(chain)。使用過濾器主要包括:

  • 編寫過濾器類

  • 定制請求(request)和響應(response)

  • 為特定的Web資源指定過濾器鏈

6.5.1.1. 編寫過濾器類

編寫過濾器的API是javax.servlet包中Filter,、FilterChain和FilterConfig接口中定義的一些方法,。定義一個過濾器就是實現(xiàn)Filter接口。Filter接口中最主要的方法是doFilter()方法,,它接收三個參數(shù):request對象,、response對象、filterchain對象,。

void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

這個方法能夠執(zhí)行的動作包括:

  • 檢查請求(request)的頭信息

  • 定制request對象,,改變請求(request)的頭信息或數(shù)據(jù)

  • 定制response對象,改變響應(response)的頭信息或數(shù)據(jù)

  • 調(diào)用在過濾器鏈中的下一個實體。如果當前過濾器是鏈中的最后一個過濾器,,那么下一個實體就是客戶請求(request)的資源,;否則,鏈中的下一個過濾器會被調(diào)用,。通過chain對象的doFilter()方法調(diào)用下一個實體,,并傳遞request對象和response對象作為參數(shù)。另外,,也可以不調(diào)用doFilter()方法阻塞請求(request),,這樣,過濾器應該負責填充對客戶的響應(response),。

  • 檢查響應的頭信息

  • 拋出異常顯示處理過程中的錯誤

除了doFilter()方法,,開發(fā)人員也必須實現(xiàn)init()和destroy()方法。當容器創(chuàng)建過濾器實例時調(diào)用init()方法,,

void init(FilterConfig filterConfig)

可以從FilterConfig對象中獲得初始化參數(shù),。

在doFilter()方法中,過濾器可以從FilterConfig對象獲得ServletContext對象,,那么就可以訪問存儲在ServletContext中的屬性對象,。當過濾器完成特定的處理過程后,調(diào)用chain對象的doFilter()方法,。例如

public final class HitCounterFilter implements Filter { private FilterConfig filterConfig = null; // 初始化 public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } // 結束 public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (filterConfig == null) return; StringWriter sw = new StringWriter(); PrintWriter writer = new PrintWriter(sw); writer.println(' ... '); . . . writer.flush(); // 輸出日志 filterConfig.getServletContext(). log(sw.getBuffer().toString()); ... //調(diào)用在過濾器鏈中的下一個實體 chain.doFilter(request, wrapper); ... }}6.5.1.2. 定制請求和響應

有許多方法可以改變請求(request)或者響應(response),。例如過濾器能夠給請求(request)增加屬性或在響應(response)中插入數(shù)據(jù)。

過濾器如果需要改變響應(response)必須在響應(response)返回給客戶端之前捕獲它,。要做到這一點需要傳遞“替身”流(stream)給Servlet,,然后利用“替身”stream產(chǎn)生響應(response)?!疤嫔怼眘tream防止了當響應(response)結束后關閉了原始的響應(response)輸出流,,并且允許過濾器改變Servlet的響應(response)。

過濾器產(chǎn)生“替身”stream

為了給Servlet傳遞“替身”stream,,過濾器需要創(chuàng)建response對象的包裝類并且覆蓋getWriter或getOutputStream方法,。包裝類被FilterChain對象的doFilter方法傳遞。創(chuàng)建請求(request)的包裝類繼承ServletRequestWrapper或HttpServletRequestWrapper,,創(chuàng)建響應(response)的包裝類繼承ServletResponseWrapper或HttpServletResponseWrapper,。

以下CharResponseWrapper類包裝了響應(response):

public class CharResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter output; public String toString() { return output.toString(); } public CharResponseWrapper(HttpServletResponse response){ super(response); output = new CharArrayWriter(); } public PrintWriter getWriter(){ return new PrintWriter(output); }}

包裝類被傳遞給BookStoreServlet,BookStoreServlet把響應寫入“替身”stream,,當chain.doFilter返回,,HitCounterFilter重新找回response把它寫入緩沖,過濾器插入計數(shù)器值到緩沖中然后重新設置response的頭信息,,最后把緩沖中的內(nèi)容寫入response,。

PrintWriter out = response.getWriter();//構造包裝類CharResponseWrapper wrapper = new CharResponseWrapper( (HttpServletResponse)response);//向 doFilter 傳遞包裝類chain.doFilter(request, wrapper);CharArrayWriter caw = new CharArrayWriter();caw.write(wrapper.toString().substring(0, wrapper.toString().indexOf('</body>')-1));...caw.write('\n</body></html>');//重新設置響應長度response.setContentLength(caw.toString().length());out.write(caw.toString());out.close();6.5.1.3. 映射過濾器

Web容器使用過濾器映射來決定是否過濾Web資源,。在Web應用的部署描述文件中映射過濾器到Servlet或URL模板。

  • 在部署描述文件中加入<filter>標記 ,,此標記包括:

    1. <filter-name>:過濾器名稱

    2. <filter-class>:過濾器的實現(xiàn)類

    3. <init-params>:過濾器的初始參數(shù)

    <filter> <filter-name>Compression Filter</filter-name> <filter-class>CompressionFilter</filter-class> <init-param> <param-name>compressionThreshold</param-name> <param-value>10</param-value> </init-param></filter>

  • 在部署描述文件中加入<filter-mapping>標記,,映射過濾器到Servlet:

    <filter-mapping> <filter-name>Compression Filter</filter-name> <servlet-name>CompressionTest</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher></filter-mapping><servlet> <servlet-name>CompressionTest</servlet-name> <servlet-class>CompressionTest</servlet-class></servlet><servlet-mapping> <servlet-name>CompressionTest</servlet-name> <url-pattern>/CompressionTest</url-pattern></servlet-mapping>

    映射過濾器到URL模板:

    <filter> <filter-name>HitCounterFilter</filter-name> <filter-class>HitCounterFilter</filter-class></filter><filter-mapping> <filter-name>HitCounterFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher></filter-mapping>

    使用<url-pattern>/*<url-pattern>標記,此過濾器將使用于此web應用中的任何靜態(tài)資源或Servlet內(nèi)容,,因為任何URL都可匹配'/*'的URL模式,。

  • dispatcher元素的作用 :Servlet 2.4版的Web程序增強了filter和request dispatcher的配合功能,這樣過濾器可以根據(jù)請求分發(fā)器(request dispatcher)所使用的方法有條件地對Web請求進行過濾,。

    1. 只有當request直接來自客戶,,過濾器才生效,對應為REQUEST條件,。

    2. 只有當request被一個請求分發(fā)器使用forward()方法轉(zhuǎn)到一個Web構件時,,對應稱為FORWARD條件。

    3. 只有當request被一個請求分發(fā)器使用include()方法轉(zhuǎn)到一個Web構件時,,對應稱為INCLUDE條件。

    4. 只有當request被一個請求分發(fā)器使用“錯誤信息頁”機制方法轉(zhuǎn)到一個Web構件時,,對應稱為ERROR條件,。

    5. 第五種過濾器作用的條件可以是上面四種條件的組合。

    6. 當不使用dispatcher元素時,,客戶的直接request會被用來過濾請求,。如果請求是從一個request dispatcher轉(zhuǎn)發(fā)過來的,這個過濾器不工作,。

如下圖,,可以映射一個過濾器到一個或多個Servlet,或者可以映射一個 Servlet到多個過濾器,。

過濾器的映射

過濾器F1映射到servlet S1,,S2和S3,過濾器F2映射到servlet S2,,過濾器F3 映射到servlet S1和S2,。

6.5.2. Application Events

應用事件模型提供了當ServletContext,HttpSession,,ServletRequest狀態(tài)改變時的通知功能,。可以編寫事件監(jiān)聽類來響應這些狀態(tài)的改變,,并且可以配置和部署應用事件和監(jiān)聽類到Web應用,。

對于ServletContext事件,當Web應用部署,、卸載和對context增加屬性時,,事件監(jiān)聽類可以得到通知,。下表列出了ServletContext的事件類型,對應特定事件的監(jiān)聽類必須實現(xiàn)的接口和當事件發(fā)生時調(diào)用的方法,。

事件類型 接口 方法 Servlet context被創(chuàng)建 javax.servlet.ServletContextListener contextInitialized() Servlet context被注銷 javax.servlet.ServletContextListener contextDestroyed() 增加屬性 javax.servlet. ServletContextAttributesListener attributeAdded() 刪除屬性 javax.servlet. ServletContextAttributesListener attributeRemoved() 屬性被替換 javax.servlet. ServletContextAttributesListener attributeReplaced()

對于HttpSession事件,,當session激活、刪除或者session屬性的增加,、刪除和替換時,,事件監(jiān)聽類得到通知。下表列出了HttpSession的事件類型,,對應特定事件的監(jiān)聽類必須實現(xiàn)的接口和當事件發(fā)生時調(diào)用的方法,。

事件類型 接口 方法 session激活 javax.servlet.http. HttpSessionListener sessionCreated() session刪除 javax.servlet.http. HttpSessionListener sessionDestroyed() 增加屬性 javax.servlet.http. HttpSessionAttributesListener attributeAdded() 刪除屬性 javax.servlet.http. HttpSessionAttributesListener attributeRemoved() 屬性被替換 javax.servlet.http. HttpSessionAttributesListener attributeReplaced()

對于ServletRequest事件,當request初始化,、銷毀或者request屬性的增加,、刪除和替換時,事件監(jiān)聽類得到通知,。下表列出了ServletRequest的事件類型,,對應特定事件的監(jiān)聽類必須實現(xiàn)的接口和當事件發(fā)生時調(diào)用的方法。

事件類型 接口 方法 session初始化 javax.servlet.ServletRequestListener requestInitialized() session銷毀 javax.servlet.ServletRequestListener requestDestroyed() 增加屬性 javax.servlet.ServletRequestAttributeListener attributeAdded() 刪除屬性 javax.servlet.ServletRequestAttributeListener attributeRemoved() 屬性被替換 javax.servlet.ServletRequestAttributeListener attributeReplaced() 6.5.2.1. 配置事件監(jiān)聽類

配置事件監(jiān)聽類的步驟:

  1. 打開Web應用的部署描述文件web.xml

  2. 增加事件聲明標記<listener>,。事件聲明定義的事件監(jiān)聽類在事件發(fā)生時被調(diào)用,。<listener>標記必須在<filter>和<filter-mapping>標記之后和<servlet>標記之前??梢詾槊糠N事件定義多個事件監(jiān)聽類,,Apusic應用服務器按照它們在部署描述文件聲明的順序調(diào)用。例如:

    <listener> <listener-class>myApp.myContextListenerClass</listener-class></listener><listener> <listener-class>myApp.mySessionAttributeListenerClass</listener-class></listener>

  3. 編寫和部署監(jiān)聽類,。

6.5.2.2. 編寫事件監(jiān)聽類

編寫事件監(jiān)聽類的步驟:

  1. 創(chuàng)建新的類并實現(xiàn)事件對應的接口

  2. 定義不接受參數(shù),、訪問屬性為public的構造函數(shù)

  3. 實現(xiàn)接口的方法

  4. 編譯并拷貝到對應Web應用的WEB-INF/classes目錄下,或者打包成jar文件拷貝到WEB-INF/lib目錄下

6.5.2.3. 事件監(jiān)聽類模板

ServletContext 監(jiān)聽類例子:

import javax.servlet.*;public final class myContextListenerClass implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { /* 當 ServletContext 初始化時被調(diào)用,,可以在這兒 初始化 ServletContext 的相關數(shù)據(jù) */ } public void contextDestroyed(ServletContextEvent event) { /* 當 Web 應用被卸載或 Apusic 服務器關閉時被調(diào)用 */ }}

HttpSession 屬性監(jiān)聽類例子:

import javax.servlet.*;public final class mySessionAttributeListenerClass implements HttpSessionAttributesListener { public void attributeAdded(HttpSessionBindingEvent sbe) { /* 增加session屬性時被調(diào)用 */ } public void attributeRemoved(HttpSessionBindingEvent sbe) { /* 刪除session屬性時被調(diào)用 */ } public void attributeReplaced(HttpSessionBindingEvent sbe) { /* 替換session屬性時被調(diào)用 */ }}

ServletRequest 屬性監(jiān)聽類例子:

import javax.servlet.*;public final class myRequestAttributeListenerClass implements ServletRequestAttributeListener { public void attributeAdded(HttpSessionBindingEvent sbe) { /* 增加request屬性時被調(diào)用 */ } public void attributeRemoved(HttpSessionBindingEvent sbe) { /* 刪除request屬性時被調(diào)用 */ } public void attributeReplaced(HttpSessionBindingEvent sbe) { /* 替換request屬性時被調(diào)用 */ }}

-----------------------------------------------

-----------------------------------------------

Servlet和Filter的url匹配以及url-pattern詳解

      Servlet和filter是J2EE開發(fā)中常用的技術,,使用方便,配置簡單,,老少皆宜,。估計大多數(shù)朋友都是直接配置用,也沒有關心過具體的細節(jié),,今天遇到一個問題,,上網(wǎng)查了servlet的規(guī)范才發(fā)現(xiàn),servlet和filter中的url-pattern還是有一些文章在里面的,,總結了一些東西,,放出來供大家參考,以免遇到問題又要浪費時間,。

一,,servlet容器對url的匹配過程:

當一個請求發(fā)送到servlet容器的時候,,容器先會將請求的url減去當前應用上下文的路徑作為servlet的映射url,比如我訪問的是http://localhost/test/aaa.html,,我的應用上下文是test,,容器會將http://localhost/test去掉,剩下的/aaa.html部分拿來做servlet的映射匹配,。這個映射匹配過程是有順序的,,而且當有一個servlet匹配成功以后,就不會去理會剩下的servlet了(filter不同,,后文會提到),。其匹配規(guī)則和順序如下:

1.     精確路徑匹配。例子:比如servletA 的url-pattern為 /test,,servletB的url-pattern為 /* ,,這個時候,如果我訪問的url為http://localhost/test ,,這個時候容器就會先 進行精確路徑匹配,,發(fā)現(xiàn)/test正好被servletA精確匹配,那么就去調(diào)用servletA,,也不會去理會其他的servlet了,。

2.     最長路徑匹配。例子:servletA的url-pattern為/test/*,,而servletB的url-pattern為/test/a/*,此時訪問http://localhost/test/a時,,容器會選擇路徑最長的servlet來匹配,,也就是這里的servletB。

3.     擴展匹配,,如果url最后一段包含擴展,,容器將會根據(jù)擴展選擇合適的servlet。例子:servletA的url-pattern:*.action

4.     如果前面三條規(guī)則都沒有找到一個servlet,,容器會根據(jù)url選擇對應的請求資源,。如果應用定義了一個default servlet,則容器會將請求丟給default servlet(什么是default servlet,?后面會講),。

    根據(jù)這個規(guī)則表,就能很清楚的知道servlet的匹配過程,,所以定義servlet的時候也要考慮url-pattern的寫法,,以免出錯。

   對于filter,,不會像servlet那樣只匹配一個servlet,,因為filter的集合是一個鏈,,所以只會有處理的順序不同,而不會出現(xiàn)只選擇一個filter,。Filter的處理順序和filter-mapping在web.xml中定義的順序相同,。

二,url-pattern詳解

在web.xml文件中,,以下語法用于定義映射:

l 以”/’開頭和以”/*”結尾的是用來做路徑映射的,。

l 以前綴”*.”開頭的是用來做擴展映射的。

l “/” 是用來定義default servlet映射的,。

l 剩下的都是用來定義詳細映射的,。比如: /aa/bb/cc.action

所以,為什么定義”/*.action”這樣一個看起來很正常的匹配會錯,?因為這個匹配即屬于路徑映射,,也屬于擴展映射,導致容器無法判斷,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多