日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Servlet、Filter和Listener

 swiftly 2014-08-07

Java Servlet是與平臺(tái)無(wú)關(guān)的服務(wù)器端組件,運(yùn)行于Servlet容器中(如Tomcat),Servlet容器負(fù)責(zé)Servlet和客戶(hù)端的通信以及調(diào)用Servlet的方法,Servlet和客戶(hù)端的通信采用“請(qǐng)求/響應(yīng)”的模式。Servlet可完成以下功能:

1、創(chuàng)建并返回基于客戶(hù)請(qǐng)求的動(dòng)態(tài)HTML頁(yè)面。

2、創(chuàng)建可以嵌入到現(xiàn)有HTML頁(yè)面中的HTML片段。

3、與其它服務(wù)器資源(如數(shù)據(jù)庫(kù)或基于Java的應(yīng)用程序)進(jìn)行通信。

4、接收多個(gè)客戶(hù)端的輸入,并將結(jié)果廣播到多個(gè)客戶(hù)端上,例如,Servlet可以實(shí)現(xiàn)支持多個(gè)參與者的游戲服務(wù)器。

5、根據(jù)客戶(hù)請(qǐng)求采用特定的MIME(Multipurpose Internet Mail Extensions)類(lèi)型對(duì)數(shù)據(jù)過(guò)濾,例如進(jìn)行圖像格式轉(zhuǎn)換。

 

Servlet的框架由兩個(gè)包組成:javax.servlet和javax.servlet.http。在javax.servlet包中定義了所有Servlet類(lèi)必須實(shí)現(xiàn)或擴(kuò)展的通用接口和類(lèi)。在javax.servlet.http包中定義了采用HTTP協(xié)議通信的HttpServlet類(lèi)。

Servlet框架的核心是javax.servlet.Servlet接口,所有的Servlet類(lèi)都必須實(shí)現(xiàn)這個(gè)接口。Servlet接口定義的方法如下:

1、init方法,負(fù)責(zé)初始化Servlet對(duì)象。

2、service方法,負(fù)責(zé)響應(yīng)客戶(hù)端的請(qǐng)求。

3、destroy方法,當(dāng)Servlet對(duì)象退出生命周期時(shí),負(fù)責(zé)釋放占用的資源。

4、getServletConfig方法,獲得ServletConfig接口,可以得到Servlet的相關(guān)參數(shù)。

5、getServletInfo方法,獲得Servlet的相關(guān)信息。

在javax.servlet包中,GenericServlet類(lèi)實(shí)現(xiàn)了Servlet接口,在javax.servlet.http包中,HttpServlet類(lèi)擴(kuò)展了GenericServlet

類(lèi)。當(dāng)用戶(hù)開(kāi)發(fā)自己的Servlet時(shí),必須擴(kuò)展以上兩個(gè)類(lèi)中的一個(gè),如果擴(kuò)展自GenericServlet類(lèi),則必須自己實(shí)現(xiàn)service方法,

如果擴(kuò)展自HttpServlet類(lèi),則不需要自己實(shí)現(xiàn)service方法,因?yàn)镠ttpServlet類(lèi)已經(jīng)實(shí)現(xiàn)了該方法。

Servlet、Filter和Listener - poorboy030103 - poorboy030103的博客

GenericServlet類(lèi)的service方法是一個(gè)抽象方法,只有兩個(gè)參數(shù):ServletRequest和ServletResponse。HttpServlet類(lèi)的service方法也只有兩個(gè)參數(shù):HttpServletRequest和HttpServletResponse。HttpSevletRequest接口和HttpResponse接口分別擴(kuò)展自ServletRequest和ServletResponse接口,都提供了與特定協(xié)議HTTP相關(guān)的數(shù)據(jù)。

ServletRequest接口的方法如下:

getAttribute            獲得屬性值

getContentType      獲得客戶(hù)請(qǐng)求數(shù)據(jù)的MIME類(lèi)型。

getInputStream      獲得可以讀取客戶(hù)請(qǐng)求數(shù)據(jù)的輸入流。

getParameter          獲得參數(shù)值

getRemoteAddr      獲得客戶(hù)端的IP

getRemoteHost       獲得客戶(hù)端的主機(jī)名

getRemotePort              獲得客戶(hù)端的端口

setAttribute            設(shè)置屬性值。

 

ServletResponse接口的方法如下:

getOutputStream    獲得可以向客戶(hù)羰發(fā)送二進(jìn)制數(shù)據(jù)的輸出流對(duì)象ServletOutputStream

getWriter               獲得可以向客戶(hù)端發(fā)送字符數(shù)據(jù)的PrintWriter對(duì)象

getCharacterEncoding    獲得Servlet發(fā)送的響應(yīng)數(shù)據(jù)的字符編碼

getContentType      返回Servlet發(fā)送的響應(yīng)數(shù)據(jù)的MIME類(lèi)型

setCharacterEncoding    設(shè)置Servlet發(fā)送的響應(yīng)數(shù)據(jù)的字符編碼。

setContentType      設(shè)置Servlet發(fā)送的響應(yīng)數(shù)據(jù)的MIME類(lèi)型。

 

Servlet的init方法有如下兩種形式:

public void init(ServletConfig config) throws ServletException

public void init() throws ServletException

在Servlet的初始化分階段,Servlet容器會(huì)為Servlet創(chuàng)建一個(gè)ServletConfig對(duì)象,用來(lái)存放Servlet的初始化配置信息,如Servlet的初始參數(shù)。如果Servlet覆蓋了帶參數(shù)的init方法,則必須在函數(shù)體內(nèi)先調(diào)用super.init(config); 以確保config參數(shù)引用了ServletConfig對(duì)象。如果Servlet覆蓋了沒(méi)有帶參數(shù)的init方法,則不需要調(diào)用super.init(); 方法,可以通過(guò)調(diào)用getServletConfig()方法來(lái)獲得ServletConfig對(duì)象。

 

Servlet容器會(huì)為Web應(yīng)用創(chuàng)建一個(gè)唯一的全局的ServletContext對(duì)象,可以把它看成是一個(gè)Web應(yīng)用的服務(wù)器端組件的共享內(nèi)存。它有如下方法:

 etAttribute(String name,Object obj) 將一個(gè)對(duì)象與一個(gè)屬性名綁定,并存放到

ServletContext中

getAttribute(String name) 獲得指定名稱(chēng)的屬性值。

removeAttribute(String name) 刪除指定名稱(chēng)的屬性。

getAttributeNames() 返回所有屬性名的一個(gè)Enumeration對(duì)象。

getInitParameter(String name) 獲得指定名稱(chēng)的參數(shù)值,該參數(shù)是Web應(yīng)用的初始化參數(shù).

getInitParameterNames() 返回Web應(yīng)用的所有初始化參數(shù)的名稱(chēng)的Enumeration對(duì)象.

getMimeType(String file) 返回文件的MIME類(lèi)型.

getRealPath(String path) 返回網(wǎng)絡(luò)路徑path對(duì)應(yīng)的文件系統(tǒng)路徑.

getServerInfo() 返回Servlet容器的名稱(chēng)和版本

 

 

注意一般在HptpServlet的子類(lèi)中,doPost方法的實(shí)現(xiàn)合并到doGet方法中,也就是在doPost方法中簡(jiǎn)單地調(diào)用doGet方法.因?yàn)橐话闱闆r下對(duì)于GetPost請(qǐng)求,它們都是一樣的處理.

編譯了Servlet,將它打包成jar放到WEB-INF/lib目錄下,或?qū)?span style="font-family: 'Times New Roman', serif; ">Servletclass文件放到WEB-INF/classes/目錄下,再在WEB-INF/web.xml配置文件中配置這些servlet,就可以在Web應(yīng)用中訪(fǎng)問(wèn)servlet,配置如下:

 <servlet>

<servlet-name>my_servlet</servlet-name>

<servlet-class>com.mycompany.ServletClass1</servlet-class>

< init-param> <!--定義servlet的初始化參數(shù), 可以有多個(gè)init-param參數(shù)-->

< param-name>iParam< /param-name>

< param-value>2< /param-value>

< /init-param>

 

< load-on-startup>2< /load-on-startup> <!--定義servlet的加載順序-->

</servlet>

 

<servlet-mapping>

<servlet-name>my_servlet</servlet-name>

<url-pattern>*.hello</url-pattern>

</servlet-mapping>

 

Session相關(guān)

在Servlet API中定義了javax.servlet.http.HttpSession接口,Servlet容器必須實(shí)現(xiàn)這一個(gè)接口。當(dāng)一個(gè)Session開(kāi)始時(shí),Servlet容器將創(chuàng)建一個(gè)HttpSession對(duì)象,在HttpSession對(duì)象中可以存放客戶(hù)狀態(tài)的信息。Servlet容器為HttpSession對(duì)象分配一個(gè)唯一的標(biāo)識(shí)符,叫做Session ID,Servlet容器把Session ID作為Cookie保存在客戶(hù)的瀏覽器中,每次客戶(hù)發(fā)出HTTP請(qǐng)求時(shí),Servlet容器可以從HttpRequest對(duì)象中讀取Session ID,然后根據(jù)Session ID找到相應(yīng)的HttpSession對(duì)象,從而獲得客戶(hù)的狀態(tài)信息。HttpSession接口有如下方法:

getId()    返回Session ID

invalidate()      使當(dāng)前的Session失效,Servlet容器會(huì)釋放HttpSession對(duì)象占用的資源。

setAttribute(String name,Object obj)     將一對(duì)name/value屬性保存到HttpSession對(duì)象中。

getAttribute(String name)      返回名字為name的屬性值。

getAttributeNames()      返回HttpSession對(duì)象中所有的屬性名。

isNew()   判斷這個(gè)Session是不是新創(chuàng)建的。

setMaxInactiveInterval()              設(shè)定Session可以處于不活動(dòng)狀態(tài)的最大時(shí)間(以秒為單位),                                              超過(guò)這個(gè)時(shí)間,Session就會(huì)自動(dòng)失效,如果設(shè)置為負(fù)數(shù),則不                                             限制Session的不活動(dòng)狀態(tài)時(shí)間。

getMaxInactiveInterval()       返回Session可以處于不活動(dòng)狀態(tài)的最大時(shí)間。

當(dāng)客戶(hù)第一次訪(fǎng)問(wèn)Web應(yīng)用中支持Session的某個(gè)頁(yè)面時(shí),就會(huì)開(kāi)始一個(gè)新的Session,接下來(lái),當(dāng)客戶(hù)瀏覽這個(gè)Web應(yīng)用的其它頁(yè)面時(shí),始終處于同一個(gè)Session中。以下情況之一,Session就會(huì)失效:

1、客戶(hù)端關(guān)閉瀏覽器。

2、Session過(guò)期,即客戶(hù)在指定的最大時(shí)間內(nèi)沒(méi)有與Web服務(wù)器交互。

3、服務(wù)器端調(diào)用了HttpSession的invalidate()方法。

如果客戶(hù)端瀏覽器不支持或禁用Cookie,則Servlet容器無(wú)法從客戶(hù)端瀏覽器中取得作為Cookie的Session ID,也就無(wú)法跟蹤客戶(hù)的狀態(tài),因此客戶(hù)端的每次請(qǐng)求支持Session的JSP頁(yè)面時(shí),Servlet容器都會(huì)創(chuàng)建一個(gè)新的HttpSession對(duì)象。對(duì)于這種情況,需要通過(guò)HttpServletResponse的encodeURL()方法重寫(xiě)客戶(hù)請(qǐng)求的URL,它把Session ID添加到URL信息中,也就是說(shuō),對(duì)于支持Session的JSP頁(yè)面中的所有連接URL,都要調(diào)用encodeURL()方法來(lái)重寫(xiě)這些URL,例如:

對(duì)于<a href=”login.jsp”/>應(yīng)該改為<a href=”<%=response.encodeURL(“l(fā)ogin.jsp”)%>”/>

這樣,即使客戶(hù)禁用Cookie,也能使用Session來(lái)跟蹤客戶(hù)的狀態(tài)信息了。

 

Session的持久化:

Session的持久化就是將HttpSession對(duì)象從內(nèi)存中轉(zhuǎn)移到文件系統(tǒng)或數(shù)據(jù)庫(kù)中,這樣做的好處是:減少系統(tǒng)資源的占用,如果Servlet容器突然關(guān)閉或重啟,或Web應(yīng)用重啟,這些持久化了的HttpSession對(duì)象可以再重新加載進(jìn)來(lái),對(duì)于客戶(hù)端,還是使用同一個(gè)Session。

Session的持久化是由Session Manager來(lái)管理的,Tomcat提供了兩個(gè)實(shí)現(xiàn)類(lèi):

l         org.apache.catalina.session.StandarManager

l         org.apache.catalina.session.PersistentManager

1、StandarManager是默認(rèn)的Session Manager。它的實(shí)現(xiàn)機(jī)制是:當(dāng)Tomcat服務(wù)器關(guān)閉或重啟,或Web應(yīng)用被重新加載時(shí),會(huì)將內(nèi)存中所有的HttpSession對(duì)象保存到文件系統(tǒng)中,默認(rèn)的文件路徑是:%CATALINA_HOME%\work\Catalina\<applicaton-name>\SESSIONS.ser

重啟Tomcat后,Tomcat服務(wù)器把SESSIONS.ser中的持久化HttpSession對(duì)象加載到內(nèi)存中。

2、PersistentManager能夠把HttpSession對(duì)象保存到Session Store中,它提供了比較StandarManager更靈活的管理功能,具有容錯(cuò)能力,控制內(nèi)存中HttpSession對(duì)象的數(shù)目等。

Tomcat實(shí)現(xiàn)Session Store的接口為org.apache.catalina.session.Store,目前提供了兩個(gè)實(shí)現(xiàn)這一接口的類(lèi):org.apache.catalina.session.FileStore和org.apache.catalina.session.JDBCStore。FileStore會(huì)將HttpSession對(duì)象保存到文件系統(tǒng)中;而JDBCStore則將HttpSession對(duì)象保存到數(shù)據(jù)庫(kù)表中。

下面給出這兩個(gè)類(lèi)的配置:

配置FileStore:

在server.xml中,在Web應(yīng)用的<Context>元素加入<Manager>元素,例如:

<Context path=”/helloapp” docBase=”helloapp” debug=”0” reloadable=”true”>

       <Manager className=”org.apache.catalina.session.PersistentManager”>

              debug=0;

              saveOnRestart=”true”

              maxActiveSessions=”-1”

              minIdleSwap=”-1”

              maxIdleSwap=”-1”

              maxIdleBackup=”-1”

              <Store className=”org.apache.catalina.session.FileStore” directory=”mydir”/>

       </Manager>

</Context>

 

 

屬性

 

作用

 

className

 

指定Session Manager的實(shí)現(xiàn)類(lèi)名,或Session Store的實(shí)現(xiàn)類(lèi)名

 

debug

 

設(shè)定Session Manager采用的跟蹤級(jí)別,取值0到99,越小越跟蹤信息越少,發(fā)布產(chǎn)品時(shí),應(yīng)該設(shè)置為0,以提高性能。

 

saveOnRestart

 

如果為true,則當(dāng)Tomcat關(guān)閉時(shí),所有的有效HttpSession對(duì)象都保存到Session Store中;當(dāng)Tomcat重啟時(shí),加載這些HttpSession對(duì)象。

 

maxActiveSessions

 

設(shè)置處于活動(dòng)狀態(tài)的Session的最大數(shù)目,如果超過(guò)這一數(shù)目,Tomcat把一些超過(guò)的Sessin對(duì)象保存到Session Store中。-1表示不限制。

 

minIdleSwap

 

Session處于不活動(dòng)狀態(tài)的最小時(shí)間,單位為秒,超過(guò)這一時(shí)間,Tomcat有可能把這個(gè)Session對(duì)象移到Session Store中。

 

maxIdleSwap

 

Session處于不活動(dòng)狀態(tài)的最大時(shí)間,超過(guò)這一時(shí)間,Tomcat就一定會(huì)將這個(gè)Session對(duì)象移到Session Store中。

 

maxIdleBackup

 

Session處于不活動(dòng)狀態(tài)的最大時(shí)間,超過(guò)這一時(shí)間,Tomcat就就會(huì)將這個(gè)Session對(duì)象拷貝到Session Store中進(jìn)行備份。

 

directory

 

指定Session Store在哪個(gè)文件系統(tǒng)目錄下存放持久化的Session對(duì)象的信息,文件名是Session ID.session。

 

配置JDBCStore:

在server.xml中,在Web應(yīng)用的<Context>元素加入<Manager>元素,例如:

<Context path=”/helloapp” docBase=”helloapp” debug=”0” reloadable=”true”>

       <Manager className=”org.apache.catalina.session.PersistentManager”>

              debug=0;

              saveOnRestart=”true”

              maxActiveSessions=”-1”

              minIdleSwap=”-1”

              maxIdleSwap=”-1”

              maxIdleBackup=”-1”

              <Store className=”org.apache.catalina.session.JDBCStore”

                     driverName=”com.mysql.jdbc.Driver”

                     connectionURL=”jdbc:mysql://localhost:3306/demo?user=root password=1234”

                     sessionTable=”tomcat_sessions”

                     sessionIdCol=”session_id”

                     sessionDataCol=”session_data”

                     sessionValidCol=”session_valid”

                     sessionMaxInactiveCol=”max_inactive”

                     sessionLastAccessedCol=”last_access”

                     sessionAppCol=”app_name”

                     checkInterval=”60”

                     debug=”0”

              />

       </Manager>

</Context>

說(shuō)明:上面的元素屬性的含義與FileStore的相同,上面的配置假設(shè)在MySQL服務(wù)器上的demo數(shù)據(jù)庫(kù)的tomcat_sessions表中存放持久化Session對(duì)象的信息,這個(gè)表的結(jié)構(gòu)如下:

CREATE TABLE tomcat_sessions(

       session_id VARCHAR(10) NOT NULL PRIMARY KEY,

       session_data MEDIUMBLOB,

       session_valid CHAR(1) NOT NULL,

       max_inactive   INT NOT NULL,

       last_access     BIGINT NOT NULL,

       app_name       VARCHR(255),

       KEY kapp_name(app_name)

);

 

Filter相關(guān)

Servlet過(guò)濾器是在Java Servlet規(guī)范2.3中定義的,它能夠?qū)ervlet容器的請(qǐng)求和響應(yīng)對(duì)象進(jìn)行檢查和修改,它在Servlet被調(diào)用之前檢查Request對(duì)象,修改Request Header和Request內(nèi)容;在Servlet被調(diào)用之后檢查Response對(duì)象,修改Response Header和Response內(nèi)容。Servlet過(guò)濾器負(fù)責(zé)過(guò)濾的Web組件可以是Servlet、JSP或HTML文件,具有以下特點(diǎn):

l         Servlet過(guò)濾器可能檢查和修改ServletRequest和ServletResponse對(duì)象

l         可以指定Servlet過(guò)濾器和特定的URL關(guān)聯(lián),只有當(dāng)客戶(hù)請(qǐng)求訪(fǎng)問(wèn)此URL時(shí),才會(huì)觸發(fā)該過(guò)濾器工作

l         多個(gè)Servlet過(guò)濾器可以被串聯(lián)起來(lái),形成管道效應(yīng),協(xié)同修改請(qǐng)求和響應(yīng)對(duì)象

l         所有支持Java Servlet規(guī)范2.3的Servlet容器,都支持Servlet過(guò)濾器

 

所有的Servlet過(guò)濾器類(lèi)都必須實(shí)現(xiàn)javax.servlet.Filter接口。該接口定義了以下3個(gè)方法:

l         init(FilterConfig)     這是Servlet過(guò)濾器的初始化方法,Servlet容器創(chuàng)建Servlet過(guò)濾器實(shí)例后就會(huì)調(diào)用這個(gè)方法。在這個(gè)方法中可以通過(guò)FilterConfig來(lái)讀取web.xml文件中Servlet過(guò)濾器的初始化參數(shù)。

l         doFilter(ServletRequest, ServletResponse, FilterChain)  這是完成實(shí)際的過(guò)濾操作的方法,當(dāng)客戶(hù)請(qǐng)求訪(fǎng)問(wèn)與過(guò)濾器關(guān)聯(lián)的URL時(shí),Servlet容器先調(diào)用該方法。FilterChain參數(shù)用來(lái)訪(fǎng)問(wèn)后續(xù)的過(guò)濾器的doFilter()方法。

l         destroy() Servlet容器在銷(xiāo)毀過(guò)濾器實(shí)例前調(diào)用該方法,在這個(gè)方法中,可以釋放過(guò)濾器占用的資源。

下面是一個(gè)過(guò)濾器的例子,它可以拒絕列在黑名單上的客戶(hù)訪(fǎng)問(wèn)留言簿,而且能將服務(wù)器響應(yīng)客戶(hù)請(qǐng)求所花的時(shí)間寫(xiě)入日志:

//WEB-INF/classes/NoteFilter.class

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class NoteFilter implements Filter{

       private FilterConfig config=null;

       private String blackList=null;

       public void init(FilterConfig config)throws ServletException{

              this.config=config;

              blackList=config.getInitParameter(“blacklist”);

       }

       public void destroy(){

              config=null;

       }

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

              throws IOException, ServletException{

              String userName=((HttpServletRequest)request).getParameter(“user_name”);

              if(userName!=null)

                     userName=new String(userName.getBytes(“ISO-8859-1”),”GB2312”);

              if(userName!=null && userName.indexOf(blackList)!=-1){

                     PrintWriter out=response.getWriter();

                     out.print(“<html><body>”);

                     out.print(“<h1>對(duì)不起,”+userName+”,你沒(méi)有權(quán)限留言</h1>”);

                     out.print(“</body></html>”);

                     out.flush();

                     return;

              }

              long before=System.currentTimeMillis();

              config.getServletContext().log(“NoteFilter:before call chain.doFilter()”);

              chan.doFilter(request, response);

              config.getServletContext().log(“NoteFilter:after call chain.doFilter()”);

              logn after=System.currentTimeMillis();

              String name=””;

              if(request instanceof HttpServletRequest)

                     name=((HttpServletRequest)request).getRequestURL();

              config.getServletContext().log(“NoteFilter:”+name+”:”+(after-before)+”ms”);

       }

}

 

發(fā)布Servlet過(guò)濾器,必須在web.xml文件中加入<filter>和<filter-mapping>元素,如下:

<filter>

       <filter-name>NoteFilter</filter>

       <filter-class>NoteFilter</filter-class>

       <init-param>

              <param-name>blackList</param-name>

              <param-value>搗蛋鬼</param-value>

       </init-param>

<filter>

<filter-mapping>

       <filter-name>NoteFilter</filter-name>

       <url-pattern>/note</url-pattern>

</filter-mapping>

 

多個(gè)過(guò)濾器可以串連起來(lái)協(xié)同工作,Servlet容器將根據(jù)它們?cè)趙eb.xml中定義的先后順序,依次調(diào)用它們的doFilter()方法。而這些過(guò)濾之間的關(guān)系不需要任何配置。

 

Listener的作用類(lèi)似于load-on-startup的Servlet,在Web應(yīng)用啟動(dòng)時(shí)被加載,在Web應(yīng)用關(guān)閉時(shí)被銷(xiāo)毀,Listener用來(lái)作為Web應(yīng)用的后臺(tái)服務(wù),比load-on-startup的Servlet更早被加載到Servlet容器中。自定義的Listener類(lèi)必須實(shí)現(xiàn)ServletContextListener接口,并實(shí)現(xiàn)該接口的兩個(gè)方法:contextInitialized(ServletContextEvent)和contextDestroyed(ServletContextEvent),例如:

public class GetConnListener implements ServletContextListener{
 public void contextInitialized(ServletContextEvent sce){
  try{
   ServletContext application=sce.getServletContext();
   String driver=application.getInitParameter("driver");
   String url=application.getInitParameter("url");
   String user=application.getInitParameter("user");
   String password=application.getInitParameter("password");
   Class.forName(driver);
   Connection conn=DriverManager.getConnection(url, user, password);
   application.setAttribute("conn", conn);
  }catch(Exception e){
   System.out.println("Listener中獲取數(shù)據(jù)庫(kù)連接出現(xiàn)異常:"+e.getMessage());
  }
 }
 public void contextDestroyed(ServletContextEvent sce){
  ServletContext application=sce.getServletContext();
  Connection conn=(Connection)application.getAtrribute("conn");
  if(conn!=null){
   try{
    conn.close();
    conn=null;
   }catch(Exception e){}
  }
 }
}

Listener配置:

<listener>

  <listener-class>lee.GetConnListener</listener-class>

</listener>

 

自定義JSP標(biāo)簽庫(kù)

實(shí)現(xiàn)自定義標(biāo)簽的處理類(lèi)

JSP容器編譯JSP網(wǎng)頁(yè)時(shí),遇到自定義標(biāo)簽,就會(huì)調(diào)用這個(gè)標(biāo)簽的處理類(lèi)。標(biāo)簽處理類(lèi)必須擴(kuò)展自javax.servlet.jsp.TagSupport類(lèi)或javax.servlet.jsp.BodyTagSupport類(lèi)。

1、TagSupport類(lèi)的主要方法如下:

l         doStartTag      JSP容器遇到自定義標(biāo)簽的起始標(biāo)志時(shí)調(diào)用該方法。

l         doEndTag       JSP容器遇到自定義標(biāo)簽的結(jié)束標(biāo)志時(shí)調(diào)用該方法。

l         setValue(String k, Object v)   在標(biāo)簽處理類(lèi)中設(shè)置key/value。

l         getValue(String k)          在標(biāo)簽處理類(lèi)中獲得key對(duì)應(yīng)的value。

l         removeValue(String k)    在標(biāo)簽處理類(lèi)中刪除key/value。

l         setPageContext(PageContext pc)   設(shè)置PageContext對(duì)象,由JSP容器在調(diào)用doStartTag或doEndTag方法之前調(diào)用。

l         setParent(Tag t)     設(shè)置該標(biāo)簽的上層標(biāo)簽的處理類(lèi),由JSP容器在調(diào)用doStartTag或 doEndTag方法之前調(diào)用。

l         getParent()     返回該標(biāo)簽的上層標(biāo)簽的處理類(lèi)。

2、TagSupport類(lèi)有兩個(gè)重要屬性:

l         parent     該標(biāo)簽的上層標(biāo)簽的處理類(lèi)。

l         pageContext    Web應(yīng)用中的javax.servlet.jsp.PageContext對(duì)象,提供了保存和訪(fǎng)問(wèn)Web應(yīng)用的共享數(shù)據(jù)方法:setAttribute(String name, Object value, int scope)和getAttribute(String name, int scope)。其中scope參數(shù)用來(lái)指定屬性存在的范圍,可選值有:PageContext.PAGE_SCOPE、PageContext.REQUEST_SCOPE、PageContext.SESSION_SCOPE和PageContext.APPLICATION_SCOPE。

注意:在TagSupport的構(gòu)造函數(shù)中不能訪(fǎng)問(wèn)pageContext成員,因?yàn)榇藭r(shí)JSP容器還沒(méi)有調(diào)用setPageContext 方法對(duì)pageContext進(jìn)行初始化。

3、處理標(biāo)簽的方法:

當(dāng)JSP容器遇到自定義標(biāo)簽的起始標(biāo)志時(shí),就會(huì)調(diào)用該標(biāo)簽處理類(lèi)的doStartTag()方法。doStartTag()方法返回一個(gè)整數(shù)值,用來(lái)決定程序的后續(xù)流程,有兩個(gè)可選值:Tag.SKIP_BODY和Tag.EVAL_BODY_INCLUDE。Tag.SKIP_BODY表示標(biāo)簽之間的內(nèi)容被忽略,例如:

<prefix:mytag>

       Hello World!

</prefix:mytag>

如果這個(gè)標(biāo)簽的處理類(lèi)的doStartTag()方法返回Tag.SKIP_BODY,則Hello World!字符串不會(huì)顯示在網(wǎng)頁(yè)上。Tag.EVAL_BODY_INCLUDE表示標(biāo)簽之間的內(nèi)容會(huì)被處理。

當(dāng)JSP容器遇到自定義標(biāo)簽的結(jié)束標(biāo)志時(shí),就會(huì)調(diào)用該標(biāo)簽處理類(lèi)的doEndTag()方法。doEndTag()方法也返回一個(gè)整數(shù)值,表示程序的后續(xù)流程,也是有兩個(gè)可選值:Tag.SKIP_PAGE和Tag.EVAL_PAGE。Tag.SKIP_PAGE表示立刻停止執(zhí)行JSP頁(yè)面,該標(biāo)簽的結(jié)束標(biāo)志之后的所有頁(yè)面內(nèi)容全部會(huì)初忽略,任何已有的輸出內(nèi)容立刻返回到客戶(hù)的瀏覽器上;Tag.EVAL_PAGE表示按正常的流程繼續(xù)執(zhí)行JSP頁(yè)面的內(nèi)容。

4、自定義標(biāo)簽的屬性

例如:<prefix:mytag attribute1=”value1”>…</prefix:mytag>

那么在標(biāo)簽處理類(lèi)中必須將這個(gè)屬性作為類(lèi)的成員變量,并且必須提供相應(yīng)的getter和setter方法,例如:

private int attribute1;

public void setAttribute1(int value){ attribute1=value;}

public int getAttribute1(){return attribute1;}

以下是一個(gè)自定義標(biāo)簽<message>的處理類(lèi)的例子:

// WEB-INF/classess/mypack/MessageTag.class

package mypack;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.JspTagException;

import javax.servlet.jsp.TagSupport;

import javax.servlet.http.HttpSession;

import java.util.Properties;

import java.io.*;

public class MessageTag extends TagSupport{

       private String key=null;

       public MessageTag(){}

       public void setKey(String key){

              this.key=key;

       }

       public String getKey(){

              return key;

       }

       public int doEndTag() throws JspException{

              try{

                     pageContext.getOut.print(key);

              }catch(Exception e){

                     throw new JspTagException(e.getMessage());

              }

              return SkIP_BODY;

       }

       public void release(){

              super.release();

       }

}

創(chuàng)建標(biāo)簽庫(kù)描述文件(Tag Library Descriptor, TLD)

TLD文件中的元素可分為3類(lèi):

l         <taglib>元素用來(lái)設(shè)置標(biāo)簽庫(kù)的相關(guān)信息,它有如下屬性:

tlibversion       指定標(biāo)簽庫(kù)的版本

jspversion       指定JSP的版本

shortname      指定標(biāo)簽庫(kù)默認(rèn)的前綴名(prefix)

uri                 設(shè)置標(biāo)簽庫(kù)的唯一訪(fǎng)問(wèn)標(biāo)示符

info                標(biāo)簽庫(kù)的說(shuō)明信息

l         <tag>元素用來(lái)定義一個(gè)標(biāo)簽,它的屬性如下:

name              標(biāo)簽的名字

tagclass          標(biāo)簽的處理類(lèi)

bodycontent    標(biāo)簽主體(body)的內(nèi)容

info                標(biāo)簽的說(shuō)明信息

說(shuō)明:bodycontent屬性有3個(gè)可選值:empty、JSP和tagdependent。empty表示標(biāo)簽沒(méi)有主體,JSP表示標(biāo)簽的主體中可以加入JSP代碼,tagdependent表示標(biāo)簽的主體的內(nèi)容由標(biāo)簽的處理類(lèi)自己去處理。

l         <attribute>元素用來(lái)定義標(biāo)簽的屬性,它有如下屬性:

name              屬性名

required          該屬性是否必須,默認(rèn)是false

rtexprvalue     該屬性的值是否可能通過(guò)”<%=…%>”的方式獲得,當(dāng)設(shè)置為true時(shí),該屬性就可以采用如下的方式設(shè)置值:<% int num=1;%> <prefix:mytag attribute1=”<%=num%>”/>

以下是一個(gè)標(biāo)簽庫(kù)描述文件的例子:

<!--WEB-INF/mytag.tld-->

<?xml version=”1.0” encoding=”ISO-8859-1”?>

<!DOCTYPE taglib PUBLIC “-//Sun Microsystems,Inc.//DTD JSP TagLibrary 1.1//EN”

       “http://java./j2ee/dtds/web-jsptaglibrary_1_1.dtd”>

<taglib>

       <tlibversion>1.0</tlibversion>

       <jspversion>1.1</jspversion>

       <shortname>mytaglib</shortname>

       <uri>/mytaglib</uri>

      

       <tag>

              <name>message</name>

              <tagclass>mypack.MessageTag</tagclass>

              <bodycontent>empty</bodycontent>

              <info>produce message by key</info>

             

              <attribute>

                     <name>key</name>

                     <required>true</required>

                     <rtexprvalue>true</rtexprvalue>

              </attribute>

       </tag>

</taglib>

在web.xml文件中加入標(biāo)簽庫(kù)的定義

<taglib>

       <!--標(biāo)簽庫(kù)的唯一標(biāo)示符,與標(biāo)簽庫(kù)描述文件中的<uri>元素的內(nèi)容相同,在JSP頁(yè)面中,也要通過(guò)這個(gè)定義來(lái)使用標(biāo)簽庫(kù)-->

       <taglib-uri>/mytaglib</taglib-uri> 

       <!--指定標(biāo)簽庫(kù)描述文件所在的位置-->

       <taglib-location>/WEB-INF/mytaglib.tld</taglib-location>

</taglib>

在JSP頁(yè)面中使用自定義的標(biāo)簽

例如:

<%@ taglib uri=”/mytaglib” prefix=”mm”%>

<html>

<body>

       <mm:message key=”hello world!”/>

</body>

</html>

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多