JSP 過濾器+Cookie+Session

過濾器

過濾器可以動態的攔截請求和相應,以變換或使用包含在請求或響應中的信息。

過濾器是可用于 Servlet 編程的 Java 類,可以實現以下目的:

  • 在客戶端的請求訪問后端資源之前,攔截這些請求。
  • 在服務器的響應發送回客戶端之前,處理這些響應。

根據規范建議的各種類型的過濾器:

  • 身份驗證過濾器(Authentication Filters)。
  • 數據壓縮過濾器(Data compression Filters)。
  • 加密過濾器(Encryption Filters)。
  • 觸發資源訪問事件過濾器。
  • 圖像轉換過濾器(Image Conversion Filters)。
  • 日志記錄和審核過濾器(Logging and Auditing Filters)。
  • MIME-TYPE 鏈過濾器(MIME-TYPE Chain Filters)。
  • 標記化過濾器(Tokenizing Filters)。
  • XSL/T 過濾器(XSL/T Filters),轉換 XML 內容。

Servlet 過濾器方法

過濾器是一個實現了 javax.servlet.Filter 接口的 Java 類。javax.servlet.Filter 接口定義了三個方法:

  • public void doFilter (ServletRequest, ServletResponse, FilterChain)
    該方法完成實際的過濾操作,當客戶端請求方法與過濾器設置匹配的URL時,Servlet容器將先調用過濾器的doFilter方法。FilterChain用戶訪問后續過濾器。
  • public void init(FilterConfig filterConfig)
    web 應用程序啟動時,web 服務器將創建Filter 的實例對象,并調用其init方法,讀取web.xml配置,完成對象的初始化功能,從而為后續的用戶請求作好攔截的準備工作(filter對象只會創建一次,init方法也只會執行一次)。開發人員通過init方法的參數,可獲得代表當前filter配置信息的FilterConfig對象。
  • public void destroy()
    Servlet容器在銷毀過濾器實例前調用該方法,在該方法中釋放Servlet過濾器占用的資源。

FilterConfig 使用

Filter 的 init 方法中提供了一個 FilterConfig 對象。

web.xml 文件配置如下:

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.runoob.test.LogFilter</filter-class>
    <init-param>
        <param-name>Site</param-name>
        <param-value>Lisy</param-value>
    </init-param>
</filter>

在 init 方法使用 FilterConfig 對象獲取參數:

public void  init(FilterConfig config) throws ServletException {
    // 獲取初始化參數
    String site = config.getInitParameter("Site"); 
    // 輸出初始化參數
    System.out.println("網站名稱: " + site); 
}

過濾器的應用順序
web.xml 中的 filter-mapping 元素的順序決定了 Web 容器應用過濾器到 Servlet 的順序。若要反轉過濾器的順序,您只需要在 web.xml 文件中反轉 filter-mapping 元素即可。
web.xml配置各節點說明

  • <filter>指定一個過濾器。
    • <filter-name>用于為過濾器指定一個名字,該元素的內容不能為空。
    • <filter-class>元素用于指定過濾器的完整的限定類名。
    • <init-param>元素用于為過濾器指定初始化參數,它的子元素<param-name>指定參數的名字,<param-value>指定參數的值。
    • 在過濾器中,可以使用FilterConfig接口對象來訪問初始化參數。
  • <filter-mapping>元素用于設置一個 Filter 所負責攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑
    • <filter-name>子元素用于設置filter的注冊名稱。該值必須是在<filter>元素中聲明過的過濾器的名字
    • <url-pattern>設置 filter 所攔截的請求路徑(過濾器關聯的URL樣式)
  • <servlet-name>指定過濾器所攔截的Servlet名稱。調用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認REQUEST。用戶可以設置多個
  • <dispatcher>子元素用來指定 Filter 對資源的多種調用方式進行攔截。
  • <dispatcher>子元素可以設置的值及其意義
    • REQUEST:當用戶直接訪問頁面時,Web容器將會調用過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那么該過濾器就不會被調用。
    • INCLUDE:如果目標資源是通過RequestDispatcher的include()方法訪問時,那么該過濾器將被調用。除此之外,該過濾器不會被調用。
    • FORWARD:如果目標資源是通過RequestDispatcher的forward()方法訪問時,那么該過濾器將被調用,除此之外,該過濾器不會被調用。
    • ERROR:如果目標資源是通過聲明式異常處理機制調用時,那么該過濾器將被調用。除此之外,過濾器不會被調用。

Cookie處理

Cookie是存儲在客戶機的文本文件,它們保存了大量軌跡信息。在servlet技術基礎上,JSP顯然能夠提供對HTTP cookie的支持。

通常有三個步驟來識別回頭客:

  • 服務器腳本發送一系列cookie至瀏覽器。比如名字,年齡,ID號碼等等。
  • 瀏覽器在本地機中存儲這些信息,以備不時之需。
  • 當下一次瀏覽器發送任何請求至服務器時,它會同時將這些cookie信息發送給服務器,然后服務器使用這些信息來識別用戶或者干些其它事情。

Cookie 剖析

HTTP/1.1 200 OK
Date: Fri, 04 Feb 2015 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=runoob; expires=Friday, 04-Feb-07 22:03:38 GMT; 
                 path=/; domain=runoob.com
Connection: close
Content-Type: text/html

Set-Cookie信息頭包含一個鍵值對,一個GMT(格林尼治標準)時間,一個路徑,一個域名。鍵值對會被編碼為URL。有效期域是個指令,告訴瀏覽器在什么時候之后就可以清除這個cookie。
如果瀏覽器被配置成可存儲cookie,那么它將會保存這些信息直到過期。如果用戶訪問的任何頁面匹配了cookie中的路徑和域名,那么瀏覽器將會重新將這個cookie發回給服務器。

Servlet Cookie 方法

  • public void setDomain(String pattern)
    設置cookie的域名,比如w3cschool.cc
  • public String getDomain()
    獲取cookie的域名,比如w3cschool.cc
  • public void setMaxAge(int expiry)
    設置cookie有效期,以秒為單位,默認有效期為當前session的存活時間
  • public int getMaxAge()
    獲取cookie有效期,以秒為單位,默認為-1 ,表明cookie會活到瀏覽器關閉為止
  • public String getName()
    返回 cookie的名稱,名稱創建后將不能被修改
  • public void setValue(String newValue)
    設置 cookie的值
  • public String getValue()
    獲取cookie的值
  • public void setPath(String uri)
    設置cookie 的路徑,默認為當前頁面目錄下的所有URL,還有此目錄下的所有子目錄
  • public String getPath()
    獲取cookie 的路徑
  • public void setSecure(boolean flag)
    指明cookie是否要加密傳輸
  • public void setComment(String purpose)
    設置注釋描述 cookie的目的。當瀏覽器將cookie展現給用戶時,注釋將會變得非常有用
  • public String getComment()
    返回描述cookie目的的注釋,若沒有則返回null

使用JSP設置Cookie
使用JSP設置cookie包含三個步驟:
(1)創建一個Cookie對象: 調用Cookie的構造函數,使用一個cookie名稱和值做參數,它們都是字符串。

Cookie cookie = new Cookie("key","value");

請務必牢記,名稱和值中都不能包含空格或者如下的字符:[ ] ( ) = , " / ? @ : ;
(2) 設置有效期:調用setMaxAge()函數表明cookie在多長時間(以秒為單位)內有效。下面的操作將有效期設為了24小時。

cookie.setMaxAge(60*60*24);

(3) 將cookie發送至HTTP響應頭中:調用response.addCookie()函數來向HTTP響應頭中添加cookie。

response.addCookie(cookie);

Session

HTTP是無狀態協議,這意味著每次客戶端檢索網頁時,都要單獨打開一個服務器連接,因此服務器不會記錄下先前客戶端請求的任何信息。

有三種方法來維持客戶端與服務器的會話:

  1. Cookies
    網絡服務器可以指定一個唯一的session ID作為cookie來代表每個客戶端,用來識別這個客戶端接下來的請求。
    這可能不是一種有效的方式,因為很多時候瀏覽器并不一定支持cookie,所以我們不建議使用這種方法來維持會話。
  2. 隱藏表單域
    一個網絡服務器可以發送一個隱藏的HTML表單域和一個唯一的session ID,就像下面這樣:
<input type="hidden" name="sessionid" value="12345">

這個條目意味著,當表單被提交時,指定的名稱和值將會自動包含在GET或POST數據中。每當瀏覽器發送一個請求,session_id的值就可以用來保存不同瀏覽器的軌跡。
這種方式可能是一種有效的方式,但點擊<A HREF>標簽中的超鏈接時不會產生表單提交事件,因此隱藏表單域也不支持通用會話跟蹤。

  1. 重寫URL
    可以在每個URL后面添加一些額外的數據來區分會話,服務器能夠根據這些數據來關聯session標識符。舉例來說,http://w3cschool.cc/file.htm;sessionid=12345, session標識符為sessionid=12345,服務器可以用這個數據來識別客戶端。
    相比而言,重寫URL是更好的方式來,就算瀏覽器不支持cookies也能工作,但缺點是您必須為每個URL動態指定session ID,就算這是個簡單的HTML頁面。

session對象
除了以上幾種方法外,JSP利用servlet提供的HttpSession接口來識別一個用戶,存儲這個用戶的所有訪問信息。
默認情況下,JSP允許會話跟蹤,一個新的HttpSession對象將會自動地為新的客戶端實例化。禁止會話跟蹤需要顯式地關掉它,通過將page指令中session屬性值設為false來實現,就像下面這樣:

<%@ page session="false" %>

JSP引擎將隱含的session對象暴露給開發者。由于提供了session對象,開發者就可以方便地存儲或檢索數據。
下表列出了session對象的一些重要方法:

  • public Object getAttribute(String name)
    返回session對象中與指定名稱綁定的對象,如果不存在則返回null
  • public Enumeration getAttributeNames()
    返回session對象中所有的對象名稱
  • public long getCreationTime()
    返回session對象被創建的時間, 以毫秒為單位,從1970年1月1號凌晨開始算起
  • public String getId()
    返回session對象的ID
  • public long getLastAccessedTime()
    返回客戶端最后訪問的時間,以毫秒為單位,從1970年1月1號凌晨開始算起
  • public int getMaxInactiveInterval()
    返回最大時間間隔,以秒為單位,servlet 容器將會在這段時間內保持會話打開
  • public void invalidate()
    將session無效化,解綁任何與該session綁定的對象
  • public boolean isNew()
    返回是否為一個新的客戶端,或者客戶端是否拒絕加入session
  • public void removeAttribute(String name)
    移除session中指定名稱的對象
  • public void setAttribute(String name, Object value)
    使用指定的名稱和值來產生一個對象并綁定到session中
  • public void setMaxInactiveInterval(int interval)
    用來指定時間,以秒為單位,servlet容器將會在這段時間內保持會話有效
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • 監聽器(listener) 監聽器簡介 :監聽器就是一個實現特定接口的普通java程序,這個程序專門用于監聽另一個...
    奮斗的老王閱讀 2,533評論 0 53
  • 本文包括:1、Filter簡介2、Filter是如何實現攔截的?3、Filter開發入門4、Filter的生命周期...
    廖少少閱讀 7,297評論 3 56
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,314評論 11 349
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,709評論 18 399