国产午夜成人免费看片无遮挡_日本免费xxxx色视频_免费人成网上在线观看_黄网址在线永久免费观看

當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

servlet2.3

servlet2.3

更新時間:2022-05-02 文章作者:未知 信息來源:網絡 閱讀次數:

明天的Java開發什么樣?
(仙人掌工作室 2001年06月19日 14:44)

和當前的Servlet 2.2規范相比,Servlet 2.3 建議最終草案(PFD)最大的不同之處在于把filter(過濾器)和event(事件)加入了Servlet模型。過濾器提供了一種讓應用程序在任何Servlet運行之前或運行之后執行標準動作的方法。很長時間以來,Servlet規范中都沒有事件。事件提供的是特定動作的通知,特別是應用程序的啟動/結束與會話的啟動/結束,使得應用程序能夠進行某些一次性的初始化/清理操作。

事件句柄
在許多場合,應用程序一啟動就必須進行一些初始化操作。例如,創建和初始化JDBC連接時,或者創建JDBC連接池時,或者讀取在應用程序的整個生命周期內都要用到的資源時,或者進行簡單的檢查以確保應用程序要用到的某些資源確實存在時,這種情況都會發生。在遵從2.2規范的容器上,應用程序沒有保證能夠執行這類初始化操作的辦法。

在2.2規范中,部署Servlet時可以在web.xml文件中設置<load-on-startup>項目。這個元素應該包含一個正數,它決定了Servlet啟動的次序,有關該標記的更多說明,請參見Servlet規范中的web.xml DTD說明。采用這種方案有幾個問題。首先,Servlet規范說:“load-on-startup元素表示該Servlet應該(should)在Web應用程序啟動的時候裝入。”Servlet容器開發者可能把它理解成“應該裝入,但不是必須裝入”(因此,當應用程序啟動時Servlet可能沒有被裝入)。另外一個問題在于,我們是在用一種與Servlet設計意圖不同的方式使用Servlet。

Servlet有一個“請求”級的作用范圍。也就是說,按照設計,Servlet對于每個客戶端的請求執行一次。但在這里,Servlet有了“應用”級作用范圍,它執行一次然后就掛起。

在2.2規范中,Servlet還可以被卸載——容器檢查初始化Servlet,判斷出Servlet在一段時間內已經沒有使用,于是就卸載它。如果這個Servlet“占據”了一些啟動的時候它初始化的資源,那么它應該釋放這些資源。但是,Servlet不會被告知應用程序什么時候結束。Servlet的拆除方法會在應用程序關閉的時候被調用,但它無法知道是否所有其他Servlet也被卸載。當其他Servlet被卸載時,它們可能需要用到由初始化Servlet創建的資源。如果先卸載的是初始化Servlet,那么其他Servlet的處境就不妙了。

使用會話的時候也會出現完全同樣的問題,因為應用程序完全有理由在建立/拆除每一個會話的時候,做一些初始化或者清理工作。

為了解決這些問題,Servlet 2.3規范引入了事件句柄的概念。事件句柄是一些回應和處理由容器初始化的特定事件的代碼。Servlet 2.3規范定義了兩種類型的事件:應用程序事件,會話事件。對于所有這兩種事件類型,事件句柄能夠捕獲啟動和結束事件,能夠捕獲屬性改變事件。

我們將把注意力主要集中到應用程序的啟動和結束事件上,但對于其他事件類型來說,代碼也是相似的。

我們來看看事件句柄的代碼。應用程序的事件句柄必須擴展javax.servlet.ServletContextListener接口。這個接口有兩個方法,即contextDestroyed()和contextInitialized()。兩個方法都有一個ServletContextEvent參數。正如你可以猜想到的,contextInitialized()方法在應用程序啟動的時候被調用,contextDestroyed()方法在應用程序結束的時候被調用。ServletContextEvent類有一個方法,它能夠返回正在被創建或拆除的ServletContext的引用。

  舉例來說,假設你正在設計一個基于Web的簡單白頁(White Page)應用。在這個應用中,用戶通過email查找姓名和地址,如Listing 1所示。這個例子在一個Hashtable(散列表)中保存白頁的內容,散列表必須在應用程序啟動的時候創建,而且它必須保存到應用程序的ServletContext。


【Listing 1】
import javax.servlet.ServletContextListener;

public class WhitePagesListener implements ServletContextListener {
 Hashtable whitePages;
 public WhitePagesServletListener() {
 whitePages = new Hashtable();
 }
public void contextDestroyed(ServletContextEvent sce) { }
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized");
WhitePageEntry wpe = new WhitePageEntry("Kevin Jones", "555-1234");
whitePages.put("kev@dev.com", wpe);
wpe = new WhitePageEntry( "Simon Horrell", "555-8765");
whitePages.put("simon@dev.com", wpe);
wpe = new WhitePageEntry( "Don Box", "555-2137");
whitePages.put("don@dev.com", wpe);
// 把散列表保存到ServletContext
sce.getServletContext().setAttribute( "addrbook", whitePages);
}
}

代碼非常簡單。WhitePagesListener類實現了ServletContextListener。散列表由類的構造方法創建。contextDestroyed()方法什么事情也不錯,因為應用程序是被完全卸載,我們不需要清理過程。令人感興趣的部分是在contextInitialized()方法內。這個方法把我們需要的數據保存到散列表,然后把散列表保存到ServletContext。當contextInitialized()被調用時,它的參數中傳入了一個對ServletContextEvent對象的引用。ServletContextEvent類有一個getServletContext()方法,它返回的是對當前應用程序的ServletContext的引用。獲得ServletContext的引用之后,散列表就被保存到了ServletContext之中。

應用程序必須經過配置才能使用這個事件句柄,具體通過修改應用程序的部署描述器(即web.xml文件)完成:


<web-app>
<listener>
<listener-class>
 WhitePagesListener
</listener-class>
</listener>...

用這種方法可以配置任意數量的監聽器(Listener)。調用監聽器的次序就是它們在部署描述器中出現的次序。監聽器屬于Singleton,開發者必須負責進行同步。這一點對于本例來說不是特別重要,但對于所有其它類型的應用來說,它可能很重要。

過濾器
過濾器是Servlet 2.3規范中最主要的新增功能。過濾器使得Servlet開發者能夠在請求到達Servlet之前截取請求,在Servlet處理請求之后修改應答。正如我們即將看到的,過濾器的創建和安裝都很簡單。

所有的過濾器實現javax.filter.Filter接口。這個接口有三個方法:setFilterConfig()方法,在最后的規范中,這個方法很可能被兩個方法取代,取代的方法可能是init(Filterconfig config)和destroy();getFilterConfig()方法,在規范的稍后版本中這個方法可能消失;doFilter()方法。setFilterConfig()方法在第一次創建過濾器實例以及從調用鏈刪除過濾器時被調用。創建實例時,傳入過濾器的參數是一個非null的FilterConfig對象。這個對象使得過濾器能夠訪問它的名字和當前的ServletContext。初始化參數可以作為過濾器配置的一部分指定,這些參數也可以通過FilterConfig訪問。當過濾器被刪除時,傳入setFilterConfig()的是一個值為null的FilterConfig。

配置過濾器時,我們可以把過濾器關聯到一個或者多個Servlet上。只要請求傳遞到了與某個過濾器關聯的Servlet上,該過濾器就會執行。過濾器以調用鏈中一部分的形式執行,執行次序由過濾器在部署描述器(即web.xml文件)中的次序決定。容器通過調用過濾器的doFilter()方法執行過濾器。doFilter()方法的參數包括一個ServletRequest對象、一個ServletResponse對象、一個javax.servlet.FilterChain對象。

FilterChain只有一個方法doFilter(),過濾器通過調用該方法把請求和應答繼續向調用鏈的下一環傳遞。當然這也意味著,過濾器可以不再向調用鏈傳遞它,從而阻塞調用。此時,當前過濾器必須負責生成合適的應答內容。

舉一個例子,我們來看一個在調試Servlet時很有用的Servlet,如Listing 2所示。這個過濾器將輸出“下游”Servlet和過濾器設置的HttpRequest頭和HttpResponse頭。如果讓這個過濾器成為調用鏈中的第一個過濾器,它可能能夠讓我們捕獲所有的應答頭,不過容器可能決定以過濾器永遠不能了解的方式設置應答頭:


【Listing 2】下面清單中的Servlet將輸出由“下游”Servlet和 過濾器設置的HttpRequest頭和HttpResponse頭

public class DumpHeadersimplements
javax.servlet.Filter {
private FilterConfig fc;
private ServletContext ctx;
... ...

public FilterConfig getFilterConfig() {
return fc;
}
publicvoid setFilterConfig( FilterConfig filterConfig) {
fc = filterConfig;
if(fc !=null) ctx = fc.getServletContext();
}
}

這個過濾器實現了javax.servlet.Filter接口,所以它必須按照前面所顯示的實現setFilterConfig()和getFilterConfig()。setFilterContext()保存了一個對ServletContext的引用以便以后使用。

doFilter()方法的實現需要一點技巧。doFilter()的第一部分很簡單:獲取request對象,分析HTTP方法和查詢字符串,然后枚舉請求頭。代碼如Listing 3所示。


【Listing 3】下面顯示了doFilter()第一部分的實現,它獲取request對象, 分析HTTP方法和查詢字符串。

public void doFilter(
ServletRequest request,
ServletResponse response, chain)
throws java.io.IOException,
ServletException {

 // 獲得request對象
 HttpServletRequest req = (HttpServletRequest)request;

 // 重新構造HTTP請求行
 String temp;
 temp = req.getMethod() + req.getRequestURI();
 if(req.getQueryString() != null)
 temp += "?"+req.getQueryString();
 temp += " " + req.getProtocol();

 // 用ServletContext記錄HTTP請求行
 ctx.log(temp); temp = "";

 // 枚舉請求頭
 Enumeration names = req.getHeaderNames();
 while(names.hasMoreElements()) {
String name = (String)names.nextElement();
temp += name + ": " ;
Enumeration values = req.getHeaders(name);
while (values.hasMoreElements()) {
 String value = (String)values.nextElement();
 temp += value + " ";
 } // 記錄 ctx.log(temp); temp = "";
}

但處理應答比較復雜,而且它涉及到Servlet的一個新概念——封裝request和response對象。在Servlet規范以前的版本中,調用任何一個要求有[Http]ServletRequest或[Http]ServletResponse的方法時,你必須把傳遞給Servlet service方法的request和response對象傳遞給該方法。最明顯的例子就是分派請求的時候:


RequestDispatch rd = getServletContext().getRequestDispatcher("foo"); rd.forward(request, response); // or rd.include(request, response);

假設你想執行一個包含操作,然后,在把應答發送給客戶端之前又要對它進行處理,或者在把應答發送給客戶端之前從RequestDispatcher.forward()查看應答。在以前的Servlet規范中,這是不可能的。但在Servlet 2.3規范中這一切都成為可能。

新的規范定義了兩個新類,即javax.servlet.http.HttpServletRequestWrapper和javax.servlet.http.HttpServletResponseWrapper(這兩個類從它們各自的非HTTP版本繼承)。這兩個類的構造方法如下:


HttpServletRequestWrapper(HttpServletRequest request) HttpServletResponseWrapper(HttpServletResponse response)

在這些類中,這兩個方法的默認行為是把調用傳遞給它們所封裝的對象。使用這些類的時候,你一般要派生這些類并覆蓋那些感興趣的方法。對于本文的過濾器,我們必須創建一個應答封裝器,記錄對addXXXHeader()方法和setXXXHeader()方法的調用。另外,我們還想要捕獲對setStatus()、setContentLength()、setContentType()和setLocale()方法的調用。代碼如Listing 4所示,它簡單地記錄了對各個方法的調用。


【Listing 4】應答封裝器。下面的代碼為過濾器構造了一個應答封裝器, 它將記錄對addXXXHeader()和setXXXHeader()方法的調用。另外, 它還要捕獲對setStatus()、setContentLength()、setContentType()和 setLocale()方法的調用。

class HeaderResponseWrapper extends
HttpServletResponseWrapper {
ServletContext ctx;

public HeaderResponseWrapper(
HttpServletResponse response,
ServletContext ctx) {
super(response);
this.ctx = ctx;
 }

public void addCookie(Cookie cookie) {
ctx.log("Set-Cookie: " + cookie.getName() + ":" + cookie.getValue());
super.addCookie(cookie);
 }

public void addHeader(String name, String value) {
ctx.log(name + ": " + value); super.addHeader(name, value);
 }

public void addIntHeader(String name, int value) {
ctx.log(name + ": " + value); super.addIntHeader(name, value);
 }

public void addDateHeader(String name, long value) {
ctx.log(name + ": " + value); super.addDateHeader(name, value);
 }

public void setHeader( String name, String value) {
ctx.log(name + ": " + value); super.setHeader(name, value);
 }

public void setIntHeader( String name, int value) {
ctx.log(name + ": " + value); super.setIntHeader(name, value);
 }

public void setDateHeader( String name, long value) {
ctx.log(name + ": " + value); super.setDateHeader(name, value);
 }

public void setStatus(int sc) {
ctx.log("status: " + sc); super.setStatus(sc);
 }

public void setStatus( int sc, java.lang.String sm) {
ctx.log("status: " + sc); super.setStatus(sc, sm);
 }

public void setContentLength(int len) {
ctx.log("Content-Length: " + len); super.setContentLength(len);
 }

public void setContentType(java.lang.String type) {
ctx.log("Content-Type: " + type); super.setContentType(type);
 }

public void setLocale(java.util.Locale loc) {
ctx.log("locale: " + loc); super.setLocale(loc);
 }
}

在過濾器中,我們按照如下方式使用這個對象:


HttpServletResponse resp = (HttpServletResponse)response;
HeaderResponseWrapper hrespw = new HeaderResponseWrapper(resp, ctx);

System.out.println("********");

chain.doFilter(request, hrespw);

注意創建好封裝器之后chain.doFilter()方法就被調用。

定義好過濾器之后就應該安裝它。為此,web.xml中應該定義一個filter元素:


<filter>
<filter-name>
Headers Filter
</filter-name>
<filter-class>
DumpHeaders
</filter-class>
<!- optional <init-params> ->
</filter>

完成這一步之后,你還要把過濾器和你想要過濾的資源關聯起來。這時你有兩種選擇:在web.xml中,把過濾器關聯到單個命名的Servlet,或者把過濾器關聯到一個URL。如下所示:


<filter-mapping>
<filter-name>
Headers Filter
</filter-name>
<servlet-name>
AddressBookServlet
</servlet-name>
</filter-mapping>

或者:


<filter-mapping>
<filter-name>
Header Filter
</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

輸出的請求頭如下所示:


GET/AddressBook/Browse.jsp HTTP/1.1
accept: */*
referer: http://localhost/ AddressBook/
accept-language: en-gb
accept-encoding: gzip, deflate
user-agent: Mozilla/4.0 ( compatible; MSIE 5.5; Windows NT 5.0)
host: localhost
connection: Keep-Alive
cookie: JSESSIONID= E0F9646772F4448004C16122020664F1

輸出的應答頭如下所示:


Content-Type: text/html;charset=8859_1 Content-Type: text/plain

如果進行網絡跟蹤,你會發現這里少了一些東西。例如,狀態代碼沒有顯示,這是因為有一些應答頭由容器在過濾器鏈執行之前或之后設置。

過濾器有很多用途,比如驗證、轉換、加密/解密。但有一點必須注意:你可以把過濾器關聯到任意資源,而不僅僅是Servlet。如果你使用的是一個插入到其他Web服務器的Servlet引擎,Web服務器很可能會不依賴于Servlet容器獨立地提供服務。在這種情況下,Servlet容器將接收不到所有的請求,所以過濾器也就不會總是被執行。

JSP 1.1中有一個問題涉及到請求分派。如果你有一個頁面執行include操作,jsp:include有一個必須設置為true的強制性flush(刷新)屬性:


<jsp:include page="somePage" flush="true" />

這個屬性強制容器把當前緩沖區內容刷新到客戶端。這樣,JSP頁面不能再設置任意HTTP應答頭。JSP 1.2規范已經修正這個問題,jsp:include標記中現在已經可以指定flush="false"。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

国产午夜成人免费看片无遮挡_日本免费xxxx色视频_免费人成网上在线观看_黄网址在线永久免费观看

  • <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        成人h精品动漫一区二区三区| 精品99一区二区三区| 色综合婷婷久久| 亚洲免费三区一区二区| 91丝袜高跟美女视频| 亚洲一区中文日韩| 日韩一区二区在线观看视频播放| 日韩av中文字幕一区二区三区| 欧美日韩中文一区| 激情综合色综合久久综合| 国产午夜精品久久久久久久| 99天天综合性| 日韩av在线发布| 中文字幕+乱码+中文字幕一区| 色视频成人在线观看免| 美女mm1313爽爽久久久蜜臀| 国产欧美视频在线观看| 欧美日韩国产成人在线91| 激情六月婷婷久久| 亚洲精品免费在线播放| 日韩欧美精品三级| 色嗨嗨av一区二区三区| 紧缚奴在线一区二区三区| 悠悠色在线精品| 久久综合久久综合久久综合| 91黄色免费网站| 国产精品一区二区在线看| 午夜电影网一区| 中文乱码免费一区二区| 日韩欧美专区在线| 色婷婷精品久久二区二区蜜臂av| 裸体歌舞表演一区二区| 一区二区三区美女| 欧美激情在线观看视频免费| 69堂国产成人免费视频| 97久久精品人人做人人爽50路| 蜜臀久久99精品久久久久久9| 亚洲三级视频在线观看| 国产午夜亚洲精品理论片色戒| 欧美日韩黄色一区二区| 91在线高清观看| 成人国产精品免费观看视频| 国产一区二区三区在线观看精品| 日日摸夜夜添夜夜添精品视频| 亚洲欧美一区二区三区孕妇| 国产精品三级久久久久三级| 日韩女优制服丝袜电影| 欧美日韩国产精选| 日本二三区不卡| 色婷婷综合激情| 色婷婷av一区二区三区大白胸| 成人国产电影网| 国产成人高清在线| 狠狠色狠狠色综合系列| 奇米精品一区二区三区在线观看一| 伊人色综合久久天天人手人婷| 日韩精品一区二| 精品欧美一区二区久久| 精品国产乱码久久| 国产毛片精品一区| 日韩一区中文字幕| 国产日产欧美精品一区二区三区| 久久久精品国产免费观看同学| 中文字幕在线不卡视频| xfplay精品久久| 精品成人免费观看| 久久久激情视频| 国产精品国产精品国产专区不蜜| 久久―日本道色综合久久| 日韩欧美国产一区在线观看| 91精品黄色片免费大全| 在线观看视频一区二区欧美日韩| 国产成人免费在线视频| 风间由美一区二区av101| 久久国产成人午夜av影院| 精品一区二区免费在线观看| 国产毛片精品国产一区二区三区| 国产精品中文字幕日韩精品| 美女在线一区二区| 国产一区二区三区在线观看免费 | 国产精品国产精品国产专区不蜜| 国产精品国产自产拍高清av| 一区免费观看视频| 亚洲电影欧美电影有声小说| 亚洲国产精品一区二区尤物区| 欧美精品777| 成人高清视频在线| 不卡一区在线观看| 欧美少妇bbb| 日韩欧美国产1| 久久久国产午夜精品| 国产精品热久久久久夜色精品三区| 亚洲色图视频免费播放| 亚洲成人激情社区| 丝袜诱惑制服诱惑色一区在线观看| 天天影视涩香欲综合网 | 国产色综合一区| 亚洲精品大片www| 美女高潮久久久| 成人免费毛片高清视频| 欧美日韩国产免费一区二区| 国产欧美一区二区精品性| 亚洲国产精品影院| 精品中文字幕一区二区小辣椒| 不卡的av在线播放| 9191成人精品久久| 亚洲国产精品精华液2区45| 亚洲福利视频一区二区| 国产一区二区剧情av在线| 欧美日本一区二区| 亚洲国产精品t66y| 伦理电影国产精品| 欧美日韩一卡二卡| 亚洲欧美日韩一区| 丁香激情综合五月| 3d动漫精品啪啪一区二区竹菊| 国产欧美一区二区精品性色| 欧美a级一区二区| 99在线精品观看| 欧美国产97人人爽人人喊| 激情综合五月天| 在线综合亚洲欧美在线视频| 日韩伦理免费电影| 国产一区二区三区精品欧美日韩一区二区三区 | 亚洲国产精品久久人人爱| 成人涩涩免费视频| 国产精品欧美精品| 丁香亚洲综合激情啪啪综合| 久久久99精品久久| 国产精品资源站在线| 久久中文娱乐网| 激情综合色丁香一区二区| 欧美视频一区二| 亚洲va欧美va天堂v国产综合| 欧美在线观看一二区| 亚洲伊人色欲综合网| 欧洲亚洲国产日韩| 亚洲成在人线免费| 7777精品伊人久久久大香线蕉完整版 | 亚洲超碰97人人做人人爱| 97se亚洲国产综合自在线不卡| 国产精品电影院| 色一区在线观看| 性欧美大战久久久久久久久| 久久久久久久久免费| 国产成人av影院| 亚洲视频香蕉人妖| 在线一区二区视频| 日日摸夜夜添夜夜添精品视频| 日韩免费一区二区| 国产精品一区二区你懂的| 国产精品免费视频一区| 一本大道久久精品懂色aⅴ| 亚洲一二三专区| 欧美刺激脚交jootjob| 成人激情电影免费在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 欧美日韩国产成人在线免费| 精品亚洲成a人在线观看| 中文字幕成人网| 欧美日本国产视频| 国产成人鲁色资源国产91色综| 亚洲欧美激情插| 欧美成人精品二区三区99精品| 高清日韩电视剧大全免费| 亚洲一卡二卡三卡四卡五卡| 精品久久久久久久久久久久久久久| 成人av在线资源| 日韩制服丝袜先锋影音| 欧美激情在线免费观看| 欧美美女视频在线观看| 国产成人av电影在线| 三级在线观看一区二区| 国产欧美日韩另类视频免费观看| 欧美主播一区二区三区| 国产成人亚洲综合色影视| 舔着乳尖日韩一区| 亚洲精品国产品国语在线app| 久久中文娱乐网| 日韩一区二区三区观看| 一本久久a久久免费精品不卡| 韩国中文字幕2020精品| 亚洲va欧美va人人爽| 国产精品久久久久影院老司| 日韩一区二区三区免费看| 欧洲精品视频在线观看| av男人天堂一区| 精品一区二区三区不卡| 五月综合激情婷婷六月色窝| 综合av第一页| 久久久久久电影| 精品理论电影在线| 日韩一区二区高清| 欧美剧在线免费观看网站 | 欧美大片在线观看| 欧美性受xxxx黑人xyx性爽| 99精品一区二区三区| 成人一级视频在线观看| 激情小说亚洲一区| 极品美女销魂一区二区三区|