過濾器監(jiān)聽器-7 .web高級開發(fā)_第1頁
過濾器監(jiān)聽器-7 .web高級開發(fā)_第2頁
過濾器監(jiān)聽器-7 .web高級開發(fā)_第3頁
過濾器監(jiān)聽器-7 .web高級開發(fā)_第4頁
過濾器監(jiān)聽器-7 .web高級開發(fā)_第5頁
免費預(yù)覽已結(jié)束,剩余54頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

Web開發(fā)模式7.1Mode1Mode1就是指在開發(fā)中將顯示層、控制層、數(shù)據(jù)層的操作統(tǒng)一交給JSP或JavaBean來進(jìn)行處理,如下所示:客戶端JSPJavaBean數(shù)據(jù)庫requestresponseMode1的處理情況分為兩種,一種是完全使用JSP進(jìn)行開發(fā),另外一種是使用JSP+JavaBean的模式進(jìn)行開發(fā)。下面分別對這兩種模式加以說明。(1)用戶發(fā)送請求交給JSP頁面進(jìn)行處理。如果是開發(fā)小型的Web程序,為了開發(fā)快速與便利,通常會將顯示層和邏輯運算層都寫在JSP中。此種做法的優(yōu)點:1.開發(fā)速度加快。程序設(shè)計人員不需要額外編寫JavaBean和Servlet,只需要專注開發(fā)JSP頁面。2.小幅度修改程序代碼較方便。因為沒有使用到JavaBean或Servlet,所以在修改程序時,直接修改JSP后,再交給Web容器重新編譯執(zhí)行即可。而不用像寫JavaBean或Servlet要先將Java源文件編譯成類文件,再放在WEB容器上才能執(zhí)行此種做法的缺點:1.程序可讀性低。因為程序代碼和網(wǎng)頁標(biāo)記都混合在一起,這將增加維護(hù)的困難度和復(fù)雜度。2.程序可重復(fù)利用性低。由于將所有的程序代碼都直接寫在JSP頁面中,并沒有把常用的程序?qū)懗山M件以增加重用性,因此造成程序代碼過于繁雜,難以維護(hù)。(2)若將顯示操作都寫入JSP頁面中,而業(yè)務(wù)層都寫成JavaBean形式,將程序代碼封裝成組件。這樣,JavaBean將負(fù)責(zé)大部分的數(shù)據(jù)處理,如執(zhí)行數(shù)據(jù)庫操作等(類似DAO),再將數(shù)據(jù)處理后的結(jié)果返回至JSP頁面上顯示。此種做法的優(yōu)點:1.程序可讀性高。因為大部分程序代碼寫在JavaBean中,不會和網(wǎng)頁顯示標(biāo)記混合在一起,因此,在進(jìn)行后期維護(hù)時,能較為輕松。2.可重復(fù)利用性高。由于核心業(yè)務(wù)代碼使用JavaBean開發(fā),因此可重復(fù)使用此組件,可以大大減少編寫重復(fù)性代碼的開發(fā)工作。此種做法的缺點:沒有流程控制。程序中每一個JSP頁都需要檢查請求的參數(shù)是否正確、條件判斷、異常發(fā)生時的處理,而且所有的顯示操作都與具體的業(yè)務(wù)代碼緊密耦合在一起,日后的維護(hù)困難。提示:Mode1類似于之前的JSP+DAO開發(fā)就是通過JavaBean(DAO)進(jìn)行數(shù)據(jù)層的操作,然后將操作的結(jié)果交給JSP進(jìn)行顯示。總的來說,Mode1的結(jié)構(gòu)最適合小型的程序開發(fā),或是復(fù)雜度較低的程序。因為Mode1最大的優(yōu)點就是開發(fā)速度較快,但是在進(jìn)行維護(hù)時要付出更大的代價。如果程序復(fù)雜度太大,縱使可以快速的開發(fā)程序,但是后續(xù)的維護(hù)才是最重要的問題,考慮到代碼的維護(hù)在開發(fā)中的地位,所以使用更多的還是Mode27.1.2Mode2:Mode-View-Controller在Mode2中所有的開發(fā)都是以Servlet為主體展開的,由Servlet接收所有的客戶端請求,然后根據(jù)請求調(diào)用相應(yīng)的JavaBean,并將所有的顯示結(jié)果交給JSP完成,也就是俗稱的MVC設(shè)計模式:客戶端servlet1.requestJavaBean2JSP3數(shù)據(jù)庫4MVC是一個設(shè)計模式,它強(qiáng)制性地使應(yīng)用程序的輸入、處理和輸出分開。MVC設(shè)計模式被分為3個核心層,即模型層、顯示層和控制層。它們各自處理自己的任務(wù),各層的任務(wù)如下:1.顯示層(View):主要負(fù)責(zé)接收Servlet傳遞的內(nèi)容,并且調(diào)用JavaBean,將內(nèi)容顯示給客戶。2.控制層(Controller):主要負(fù)責(zé)所有的用戶請求參數(shù),判斷請求參數(shù)是否合法,根據(jù)請求的類型調(diào)用JavaBean執(zhí)行操作并將最終的處理結(jié)果交由顯示層進(jìn)行顯示。3.模型層(Model):完成一個獨立的業(yè)務(wù)操作的組件,一般都是以JAvaBean或者EJB的形式進(jìn)行定義的。在MVC設(shè)計模式中,最關(guān)鍵的部分是使用RequestDispatcher接口,因為內(nèi)容都是通過此接口保存到JSP頁面上進(jìn)行顯示的。當(dāng)用戶有請求提交時,所有請求都會交給Servlet進(jìn)行處理,然后由Servlet調(diào)用JavaBean,并將JavaBean的操作結(jié)果通過RequestDispatcher接口傳遞到JSP頁面上。由于這些要顯示的內(nèi)容只是在一次請求-回應(yīng)中有效,所以在MVC設(shè)計模式中,所有的屬性傳遞都將使用request屬性范圍傳遞,這樣可以提升代碼的操作性能。說明:為什么使用request傳遞屬性:因為保存范圍越大占用的內(nèi)存越多。4種屬性范圍分別有不同的保存時間,如果是page則保存在一個頁面,跳轉(zhuǎn)無效;如果是request則在一次服務(wù)器端跳轉(zhuǎn)后有效,選擇新連接后失效;如果是session則在一次會話有效,用戶注銷后失效;如果是application,則保存在服務(wù)器上,服務(wù)器關(guān)閉失效。如果按照這個思路理解,那么當(dāng)屬性只需要一次服務(wù)器跳轉(zhuǎn)上使用時,應(yīng)用request范圍所保存的時間是最少的,保存時間少內(nèi)存占用量也就少,所以性能是最高的。但是如果某些屬性要在一次會話中保存,則肯定就要使用session,一般都是在用戶登錄驗證中使用session屬性范圍。7.2實例操作:MVC設(shè)計模式應(yīng)用為了更好的便于大家理解程序,下面通過一個登錄程序來講解MVC設(shè)計模式在實際開發(fā)中的主要作用。在本程序中,用戶輸入的登錄信息提交給Servlet進(jìn)行接收,Servlet接收到請求內(nèi)容后首先對其合法性進(jìn)行驗證(如輸入的內(nèi)容是否為空或者長度是否滿足要求等),如果驗證失敗,則將錯誤信息傳遞給登錄頁顯示;如果數(shù)據(jù)合法,則調(diào)用DAO層完成數(shù)據(jù)庫的驗證,根據(jù)驗證的結(jié)構(gòu)跳轉(zhuǎn)到登錄成功或者登錄失敗的頁面。在本程序中,為了操作便捷,將登陸成功或失敗的顯示頁都統(tǒng)一設(shè)置成登錄頁。本程序需要的程序清單如下:NO.頁面名稱文件類型描述1UserJavaBean用戶登錄的VO操作類2DatabaseConnectionJavaBean負(fù)責(zé)數(shù)據(jù)庫的連接和關(guān)閉操作3IUserDAOJavaBean定義登錄操作的DAO接口4UserDAOImplJavaBeanDAO接口的真實實現(xiàn)類,完成具體的登錄驗證5UserDAOProxyJavaBean定義代理操作,負(fù)責(zé)數(shù)據(jù)庫打開和關(guān)閉并且調(diào)用真實主題6DAOFactoryJavaBean工廠類,取得DAO接口的實例7LoginServletSrevlet接收請求參數(shù),進(jìn)行參數(shù)驗證,調(diào)用DAO完成具體的登錄驗證,并根據(jù)DAO的驗證結(jié)果返回登錄信息8Login.jspJSP提供用戶輸入的表單,可以顯示用戶登錄成功或失敗的信息完成本程序所需要的user表結(jié)構(gòu):NO.列名稱描述1userid保存用戶的登錄id2name用戶的真實姓名3password用戶密碼實例:定義VO類-User.javapackagecom.xlh.demo.vo;publicclassUser{privateStringuserid;privateStringname;privateStringpassword;publicStringgetUserid(){returnuserid;}publicvoidsetUserid(Stringuserid){this.userid=userid;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){=name;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.password=password;}}實例:定義數(shù)據(jù)庫操作類-DatabaseConnection.javapackagecom.xlh.demo.dbc;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;publicclassDatabaseConnection{privatestaticfinalStringORACLEDRIVER="oracle.jdbc.driver.OracleDriver";

privatestaticfinalStringURL="jdbc:oracle:thin:@localhost:1521:oracle";

privatestaticfinalStringuserName="scott";

privatestaticfinalStringpassWord="OracleAdmin1";privateConnectionconn=null;publicDatabaseConnection()throwsException{try{Class.forName(ORACLEDRIVER);conn=DriverManager.getConnection(URL,userName,passWord);}catch(Exceptione){throwe;}}publicConnectiongetConn(){returnthis.conn;}publicvoidclose()throwsException{if(this.conn!=null){try{this.conn.close();}catch(Exceptione){throwe;}}}}實例:定義DAO接口-IUserDAO.javapackagecom.xlh.demo.dao;importcom.xlh.demo.vo.User;publicinterfaceIUserDAO{publicbooleanfindLogin(Useruser)throwsException;}實例:定義DAO實現(xiàn)類-UserDAOImpl.javapackagecom.xlh.demo.impl;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importcom.xlh.demo.dao.IUserDAO;importcom.xlh.demo.vo.User;publicclassUserDAOImplimplementsIUserDAO{privateConnectionconn;privatePreparedStatementpstat;publicUserDAOImpl(Connectionconn){this.conn=conn;}publicbooleanfindLogin(Useruser)throwsException{booleanflag=false;try{Stringsql="selectnamefrommy_userwhereuserid=?andpassword=?";this.pstat=conn.prepareStatement(sql);this.pstat.setString(1,user.getUserid());this.pstat.setString(2,user.getPassword());ResultSetrs=this.pstat.executeQuery();if(rs.next()){user.setName(rs.getString(1));flag=true;}}catch(Exceptione){throwe;}finally{if(this.pstat!=null){try{this.pstat.close();}catch(Exceptione){throwe;}}}returnflag;}}實例:定義DAO代理操作類-UserDAOProxy.javapackagexy;importcom.xlh.demo.dao.IUserDAO;importcom.xlh.demo.dbc.DatabaseConnection;importcom.xlh.demo.impl.UserDAOImpl;importcom.xlh.demo.vo.User;publicclassUserDAOProxyimplementsIUserDAO{privateDatabaseConnectiondbc=null;privateIUserDAOdao=null;publicUserDAOProxy(){try{this.dbc=newDatabaseConnection();}catch(Exceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}this.dao=newUserDAOImpl(this.dbc.getConn());}publicbooleanfindLogin(Useruser)throwsException{booleanflag=false;try{flag=this.dao.findLogin(user);}catch(Exceptione){throwe;}finally{this.dbc.close();}returnflag;}}實例:定義工廠類,取得DAO實例-DAOFactory.javapackagecom.xlh.demo.factory;importcom.xlh.demo.dao.IUserDAO;importxy.UserDAOProxy;publicclassDAOfactory{publicstaticUserDAOProxygetIUserDAOInstance(){returnnewUserDAOProxy();}}實例:定義Servlet-LoginServlet.javapackagecom.xlh.demo.servlet;importjava.io.IOException;importjava.io.PrintWriter;importjava.util.ArrayList;importjava.util.List;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.xlh.demo.factory.DAOfactory;importcom.xlh.demo.vo.User;publicclassLoginServletextendsHttpServlet{ publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ Stringpath="login.jsp"; Stringuserid=request.getParameter("userid");

Stringuserpass=request.getParameter("userpass"); List<String>info=newArrayList<String>(); if(userid==null||userid.equals("")){ info.add("用戶id不能為空"); } if(userpass==null||userpass.equals("")){ info.add("用戶密碼不能為空"); } if(info.size()==0){ Useruser=newUser(); user.setUserid(userid); user.setPassword(userpass); try{ if(DAOfactory.getIUserDAOInstance().findLogin(user)){ info.add("用戶登錄成功,歡迎"+user.getName()+"光臨"); }else{ info.add("用戶登錄失敗,錯誤的用戶名和密碼"); } }catch(Exceptione){ e.printStackTrace(); }

request.setAttribute("info",info); request.getRequestDispatcher(path).forward(request,response); } } publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ doGet(request,response); }}實例:定義登錄頁-login.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head>

<title>MyJSP'login.jsp'startingpage</title></head><scriptlanguage="JavaScript">functionvalidate(){

if(!(/^\w}{5,15}$/.test(f.userid.value))){alert("用戶ID必須是5-15位");f.userid.focus();

returnfalse;

}

if(!(/^\w}{5,15}$/.test(f.userpass.value))){alert("用戶ID必須是5-15位");f.userpass.focus();

returnfalse;

}

}</script><body><h2>用戶登錄程序</h2>

<%request.setCharacterEncoding("GBK");

%>

<%List<String>info=(List<String>)request.getAttribute("info");

if(info!=null){Iterator<String>iter=info.iterator();

while(iter.hasNext()){

%><h4><%=iter.next()%></h4>

<%

}

}

%><formaction="login"method="post"onSubmit="returnvalidate(this)">用戶ID:<inputtype="text"name="userid"/><br>密碼:<inputtype="password"name="userpass"/><br><inputtype="submit"value="登錄"/><inputtype="reset"value="重置"/></form></body></html>過濾器JSP可以完成的功能Servlet都可以完成,但是Servlet具備的很多功能是JSP所不具備的,從使用上看Servlet可以分為簡單Servlet、過濾Servlet(過濾器)和監(jiān)聽Servlet(監(jiān)聽器)3種。JSP可以完成的也只是簡單Servlet的功能,下面先來講解過濾器的使用。過濾器的基本概念Filter是在Servlet2.3之后增加的新功能,當(dāng)需要限制用戶訪問某些資源或者在處理請求時提前處理某些資源時,即可使用過濾器完成。過濾器是以一種組件的形式綁定到WEB應(yīng)用程序當(dāng)中的,與其他的WEB應(yīng)用程序組件不同的是,過濾器是采用鏈的方式進(jìn)行處理的,如下所示:客戶端過濾器

過濾器過濾器Web資源可以定義多個過濾器在沒有使用過濾器以前,客戶端都是直接請求Web資源的,但是一旦加入了過濾器,我們可以發(fā)現(xiàn),所有的請求都是先交給了過濾器處理,然后再訪問相應(yīng)的Web資源,可以達(dá)到對某些資源的訪問限制。提示:過濾器功能與持票瀏覽一樣如果用戶去看展覽會,肯定需要購買門票,那么過濾器就好比哪些檢票人員,如果是有票的游客(合法用戶)則可以進(jìn)去參加展會,如果沒有票的(非法用戶)則不能進(jìn)去參加展會。實現(xiàn)過濾器在Servlet中,如果定義一個過濾器,則直接讓一個類實現(xiàn)javax.servlet.Filter接口即可,此接口定義了3個操作方法,如下所示:No.方法類型描述1publicvoidinit(FilterConfigfilterConfig)throwsServletException普通過濾器初始化(容器啟動時初始化)時調(diào)用,可以通過FilterConfig取得配置的初始化參數(shù)2publicvoiddoFilter(ServletRequestrequest,SerlvetResponseresponse,FilterChainchain)throwsIOException,ServletException普通完成具體的過濾操作,然后通過FilterChain讓請求繼續(xù)向下傳遞3publicvoiddestroy()普通過濾器銷毀時使用上表中的方法中,最需要注意的是doFilter方法,在此方法中定義了ServletRequest、ServletResponse和FilterChain3個參數(shù),從前兩個參數(shù)中可以發(fā)現(xiàn),過濾器可以完成對任意協(xié)議的過濾操作。FilterChain接口的主要作用是將用戶的請求向下傳遞給其他的過濾器或者Servlet,此接口的方法如下所示:NO.方法類型描述1publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse)throwsIOException,ServletException普通將請求繼續(xù)向下傳遞在FilterChain接口中依然定義了一個同樣的doFilter方法,這是因為在一個過濾器后面可能存在另一個過濾器,也可能是請求的最終目標(biāo)(Servlet),這樣就通過FilterChain形成了一個過濾鏈的操作。所謂的過濾鏈就類似于生活中的完的擊鼓傳花游戲。在擊鼓傳花游戲中每一位參加游戲的人員都知道下一位的接收者是誰,所以只需要將花一直傳遞下去即可。在過濾器中,實際上請求就相當(dāng)于所傳的花,而傳遞時中間不管是否有何種操作,只要是符合條件的請求,都要一直傳遞下去。實例:定義一個簡單的過濾器-SimpleFilter.javapackagecom.xlh.demo.demo;publicclassSimpleFilterimplementsFilter{publicvoiddestroy(){System.out.println("過濾器銷毀");}publicvoiddoFilter(ServletRequestarg0,ServletResponsearg1,FilterChainarg2)throwsIOException,ServletException{System.out.println("**執(zhí)行doFilter方法之前**");arg2.doFilter(arg0,arg1);System.out.println("**執(zhí)行doFilter方法之后**");}publicvoidinit(FilterConfigarg0)throwsServletException{StringinitParam=arg0.getInitParameter("ref");System.out.println("**過濾器初始化,初始化參數(shù)="+initParam);}}本程序中,SimpleFilter類實現(xiàn)了Filter接口,所以要覆寫Filter接口中定義的3個方法。在doFilter方法中增加了兩條輸出語句,分別是FilterChain調(diào)用doFilter方法之前和之后,因為過濾器采用的是鏈的處理方式,所以兩條語句都會執(zhí)行。實例:配置web.xml文件<filter><filter-name>simple</filter-name><filter-class>com.xlh.demo.demo.SimpleFilter</filter-class><init-param><param-name>ref</param-name><param-value>HELLOWORLD</param-value></init-param></filter><filter-mapping><filter-name>simple</filter-name><url-pattern>/*</url-pattern></filter-mapping>過濾器配置與Servlet配置樣式非常相似,但需要注意的是,這里的<url-patten>表示一個過濾器的過濾位置,如果是“/*”表示對于根目錄下的一切操作都需要過濾,輸入URL路徑打開首頁,程序的運行結(jié)果會在Tomcat后臺輸出。我們可以從結(jié)果中清楚地發(fā)現(xiàn),過濾器中的初始化方法是在容器啟動時自動加載的,并且通過FilterConfig的getInitPrameter方法取出了配置的初始化參數(shù),只初始化一次。但是對于過濾器中的diFilter方法實際上會調(diào)用兩次,一次是FilterChain操作之前,一次是在FilterChain操作之后。提示:本程序是對一個目錄中所有內(nèi)容進(jìn)行過濾,但是在開發(fā)中,有可能只對某一個或某幾個目錄過濾,此時就可以明確的寫出是對哪個目錄過濾或是多增加過濾的映射路徑。實例:對JSP文件夾過濾-修改<url-patten><filter><filter-name>simple</filter-name><filter-class>com.xlh.demo.demo.SimpleFilter</filter-class><init-param><param-name>ref</param-name><param-value>HELLOWORLD</param-value></init-param></filter><filter-mapping><filter-name>simple</filter-name><url-pattern>/jsp/*</url-pattern></filter-mapping>實例:增加多個過濾路徑,增加多個<filter-mapping><filter-mapping><filter-name>simple</filter-name><url-pattern>/jsp/*</url-pattern></filter-mapping><filter-mapping><filter-name>simple</filter-name><url-pattern>/login.jsp</url-pattern></filter-mapping>過濾器的應(yīng)用過濾器本身是屬于一個組件的形式加入到應(yīng)用程序之中的,例如,可以使用過濾器完成編碼的過濾操作或者是用戶的登錄驗證,下面講解這兩種操作的實現(xiàn)。實例一:編碼過濾在web開發(fā)中,編碼過濾是必不可少的操作,如果按照之前的做法,在每一個JSP或Servlet中都重復(fù)編寫“request.setCharacterEnoding(“GBK”)”的語句肯定是不可取的,會造成大量的代碼重復(fù),那么此時即可通過過濾器完成這種編碼過濾。實例:編碼過濾器-EncodingFilter.javapackagecom.xlh.demo.demo;publicclassEncodingFilterimplementsFilter{privateStringcharSet;publicvoiddestroy(){}publicvoiddoFilter(ServletRequestarg0,ServletResponsearg1,FilterChainarg2)throwsIOException,ServletException{arg0.setCharacterEncoding(charSet);}publicvoidinit(FilterConfigarg0)throwsServletException{charSet=arg0.getInitParameter("charset");}}本程序中,在初始化操作時,通過FilterConfig中的getInitparamter方法取得了一個配置的初始化參數(shù),此參數(shù)的內(nèi)容是一個指定的過濾編碼,然后在doFilter方法中執(zhí)行request.setCharacterEncoding()操作,即可為所有頁面設(shè)置統(tǒng)一的請求編碼實例:配置web.xml文件<filter><filter-name>encoding</filter-name><filter-class>com.xlh.demo.demo.EncodingFilter</filter-class><init-param><param-name>charset</param-name><param-value>GBK</param-value></init-param></filter><filter-mapping><filter-name>encoding</filter-name><url-pattern>/*</url-pattern></filter-mapping>實例二:登錄驗證登錄驗證是所有Web開發(fā)中不可缺少的部分,最在的做法是通過驗證session的方式完成,但是如果每一個頁面都這樣做的話,則肯定會造成大量的代碼重復(fù),而通過過濾器的方式即可避免這種重復(fù)的操作。在這里需要注意的是,session本身是屬于HTTP協(xié)議的范疇,但是DoFilter方法中定義的是ServletRequest類型的對象,那么想要取得session,則必須進(jìn)行向下轉(zhuǎn)型操作,將ServletRequest變?yōu)镠ttpServletRequest接口對象,才能通過getSession()方法取得一個session對象。實例:登錄驗證過濾,假設(shè)登陸后保存的session屬性名稱是userid-LoginFilter.javapackagecom.xlh.demo.demo;publicclassLoginFilterimplementsFilter{publicvoiddestroy(){}publicvoiddoFilter(ServletRequestarg0,ServletResponsearg1,FilterChainarg2)throwsIOException,ServletException{HttpServletRequestreq=(HttpServletRequest)arg0;HttpSessionsession=req.getSession();if(session.getAttribute("userid")!=null){arg2.doFilter(arg0,arg1);}else{arg0.getRequestDispatcher("login.jsp").forward(arg0,arg1);}}publicvoidinit(FilterConfigarg0)throwsServletException{}}實例:配置web.xml<filter><filter-name>login</filter-name><filter-class>com.xlh.demo.demo.LoginFilter</filter-class></filter><filter-mapping><filter-name>login</filter-name><url-pattern>/*</url-pattern></filter-mapping>監(jiān)聽器第三種Servlet程序稱為監(jiān)聽器Servlet,主要功能是負(fù)責(zé)監(jiān)聽Web的各種操作,當(dāng)相關(guān)的事件觸發(fā)后將產(chǎn)生事件,并對此事件進(jìn)行處理。在Web中可以對application、session和request3種操作進(jìn)行監(jiān)聽。1.對application監(jiān)聽對application監(jiān)聽,實際上就是對ServletContext監(jiān)聽,主要使用ServletContextListener和ServletContextAttributeListener兩個接口。(1)上下文狀態(tài)監(jiān)聽:ServletContextListener接口對Servlet上下文狀態(tài)監(jiān)聽可以使用javax.servlet.ServletContextListener接口,此接口定義的方法如下所示:No.方法類型描述1publicvoidcontextInitialized(ServletContextEventsce)普通容器啟動時觸發(fā)2publicvoidcontextDestroyed(ServletContextEventsce)普通容器銷毀時觸發(fā)在上下文狀態(tài)監(jiān)聽操作中,一旦觸發(fā)了ServletContextListener接口中定義的事件后,可以通過ServletContextEvent進(jìn)行事件的處理,此事件定義的方法如下所示NO方法類型描述1publicServletContextgetServletContext()普通取得ServletContext對象在ServletContextEvent類中只定義了一個getServletContext()方法,用戶可以通過該方法取得一個ServletContext對象的實例,下面通過代碼進(jìn)行演示實例:對Servlet上下文狀態(tài)監(jiān)聽-ServletContextListenerDemo.javapackagecom.xlh.demo.demo;publicclassServletContextListenerDemoimplementsServletContextListener{publicvoidcontextDestroyed(ServletContextEventarg0){System.out.println("**容器銷毀-->"+arg0.getServletContext().getContextPath());}publicvoidcontextInitialized(ServletContextEventarg0){System.out.println("**容器初始化-->"+arg0.getServletContext().getContextPath());}}實例:配置web.xml文件<listener><listener-class>com.xlh.demo.demo.ServletContextListenerDemo</listener-class></listener>本程序在容器初始化和銷毀操作中,分別通過ServletContextEvent事件對象取得ServletContext實例,然后調(diào)用getContextPath方法獲取虛擬路徑名稱。提示:關(guān)于不同的Servlet的配置所有的Servlet程序都必須在Web.xml中進(jìn)行配置,如果一個web.xml文件要同時配置簡單的Servlet、過濾器和監(jiān)聽器的話,則建議按照以下步驟編寫配置文件1.先配置過濾器2.再配置監(jiān)聽器3.最后配置簡單Servlet2.上下文屬性監(jiān)聽:ServletContextAttributeListener接口對Servlet上下文屬性操作監(jiān)聽,可以使用javax.servlet.ServletContextAttributeListener接口,此接口定義的方法如表:NO.方法類型描述1publicvoidattributeAdded(ServletContextAttributeEvetscab)普通增加屬性時觸發(fā)2publicvoidattributeRemoved(ServletContextAttributeEvetscab)普通刪除屬性時觸發(fā)3publicvoidattributeReplaced(ServletContextAttributeEvetscab)普通替換屬性時觸發(fā)在上下文屬性監(jiān)聽中,一旦觸發(fā)了ServletCOntextAttributeListener接口中定義的事件后,可以通過ServletContextAttributeEvent進(jìn)行事件的處理,此事件定義的方法如表:No.方法類型描述1publicStringgetName()普通取得設(shè)置的屬性名稱2publicObjectgetValue()普通取得設(shè)置的屬性內(nèi)容實例:對Servlet上下文屬性監(jiān)聽-ServletContextAttributeListrenerDemo.javapublicclassServletContextAttributeListenerDemoimplementsServletContextAttributeListener{publicvoidattributeAdded(ServletContextAttributeEventarg0){System.out.println("**屬性增加-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}publicvoidattributeRemoved(ServletContextAttributeEventarg0){System.out.println("**屬性刪除-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}publicvoidattributeReplaced(ServletContextAttributeEventarg0){System.out.println("**屬性替換-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}}實例:配置web.xml文件<listener><listener-class>com.xlh.demo.demo.ServletContextAttributeListenerDemo</listener-class></listener>本程序中,在屬性的增加、替換、刪除上都編寫了具體的監(jiān)聽操作,并且通過ServletContextAttributeEvent事件取得了所操作屬性的名稱和對應(yīng)內(nèi)容。實例:設(shè)置application屬性-application_attribute_add.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'application_attribute_add.jsp'startingpage</title></head><body>

<%application.setAttribute("hello","world");

%></body></html>當(dāng)?shù)谝淮螆?zhí)行本頁面時,屬于設(shè)置一個新的屬性,則此時Tomcat后臺將顯示如下輸出信息:**屬性增加-->屬性名稱:hello,屬性內(nèi)容:world當(dāng)重復(fù)調(diào)用本頁時,屬于重復(fù)設(shè)置屬性,那么將執(zhí)行替換操作,此時Tomcat后臺將像是如下信息:**屬性替換-->屬性名稱:hello,屬性內(nèi)容:world實例:刪除屬性-application_attribute_remove.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'application_attribute_add.jsp'startingpage</title></head><body>

<%application.removeAttribute("hello");

%></body></html>當(dāng)刪除屬性時,將執(zhí)行刪除操作,此時Tomcat后臺將顯示如下輸出信息:**屬性刪除-->屬性名稱:hello,屬性內(nèi)容:world對session監(jiān)聽在監(jiān)聽器中,針對于session的監(jiān)聽操作主要使用HttpSessionListener、HttpSessionAttributeListener和HttpSessionBindingListener接口。1.Session狀態(tài)監(jiān)聽:HttpSessionListener接口當(dāng)需要對創(chuàng)建或銷毀session的操作進(jìn)行監(jiān)聽時,可以實現(xiàn)javax.servlet.http.HttpSessionListener接口,此接口定義的方法如下所示:NO.方法類型描述1publicvoidsessionCreated(HttpSessionEventse)普通Session創(chuàng)建時調(diào)用2publicvoidsessionDestroyed(HttpSessionEventse)普通Session銷毀時調(diào)用當(dāng)session創(chuàng)建或銷毀后,將產(chǎn)生HttpSessionEvent事件,此事件定義的方法如下所示:NO.方法類型描述1publicHttpSessiongetSession()普通取得當(dāng)前的session實例:對session監(jiān)聽-HttpSessionListenerDemo.javapublicclassHttpSessionListenerDemoimplementsHttpSessionListener{publicvoidsessionCreated(HttpSessionEventarg0){System.out.println("**SESSION創(chuàng)建,SESSIONID="+arg0.getSession().getId());}publicvoidsessionDestroyed(HttpSessionEventarg0){System.out.println("**SESSION銷毀,SESSIONID="+arg0.getSession().getId());}}實例:配置web.xml文件<listener><listener-class>com.xlh.demo.demo.HttpSessionListenerDemo</listener-class></listener>本程序在進(jìn)行session創(chuàng)建以及銷毀時,會將當(dāng)前的sessionid輸出,頁面運行后Tomcat后臺輸出:**SESSION創(chuàng)建,SESSIONID=0E12A9207616782269CBAF55D877D24E、當(dāng)一個session被服務(wù)器銷毀時后臺將顯示:**SESSION銷毀,SESSIONID=0E12A9207616782269CBAF55D877D24E注意:當(dāng)一個新用戶打開一個動態(tài)頁時,服務(wù)器會為新用戶分配session,并且觸發(fā)HttpSessionListener接口中的sessionCreated()事件,但是在用戶銷毀時卻有兩種不同的方式來觸發(fā)sessionDestroyed()事件。方式一:調(diào)用HttpSession接口的invalidate()方法,讓一個session失效。方式二:超過了配置的session超時時間,session超時時間可以直接在項目的web.xml中配置。范例:配置session超時時間<session-config><session-timeout>5</session-timeout></session-config>以上將一個session的超時時間配置成了5分鐘,如果一個用戶在5分鐘后沒有與服務(wù)器進(jìn)行任何交互操作的話,那么服務(wù)器會認(rèn)為此用戶已經(jīng)離開,會自動將其注銷。如果沒有在項目中配置超時時間,則Tomcat中默認(rèn)的超時時間為30分鐘。2.Session屬性監(jiān)聽:HttpSessionAttributeListener接口在session監(jiān)聽中也可以對session的屬性操作進(jìn)行監(jiān)聽,這一點與監(jiān)聽上下文屬性的道理一樣。要對session屬性操作監(jiān)聽,則可以使用javax.servlet.http.HttpSessionAttributeListener接口完成,此接口定義的方法如下所示:NO.方法類型描述1publicvoidattributeAdded(HttpSessionBingdingEventse)普通增加屬性時觸發(fā)2publicvoidattributeRemoved(HttpSessionBingdingEventse)普通刪除屬性時觸發(fā)3publicvoidattributeReplaced(HttpSessionBingdingEventse)普通替換屬性時觸發(fā)當(dāng)進(jìn)行屬性操作時,將根據(jù)屬性的操作觸發(fā)HttpSessionAttributeListener接口中的方法,每個操作方法都將產(chǎn)生HttpSessionBindingEvent事件,此事件定義的方法如下所示:No.方法類型描述1publicHttpSessiongetSession()普通取得session2publicStringgetName()普通取得屬性名稱3publicObjectgetValue()普通取得屬性內(nèi)容實例:對session的屬性操作監(jiān)聽-HttpSessionAttributeListenerDemo.javapublicclassHttpSessionAttributeListenerDemoimplementsHttpSessionAttributeListener{publicvoidattributeAdded(HttpSessionBindingEventarg0){System.out.println(arg0.getSession().getId()+",增加屬性-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}publicvoidattributeRemoved(HttpSessionBindingEventarg0){System.out.println(arg0.getSession().getId()+",刪除屬性-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}publicvoidattributeReplaced(HttpSessionBindingEventarg0){System.out.println(arg0.getSession().getId()+",替換屬性-->屬性名稱:"+arg0.getName()+",屬性內(nèi)容:"+arg0.getValue());}}實例:配置web.xml文件<listener><listener-class>com.xlh.demo.demo.HttpSessionAttributeListenerDemo</listener-class></listener>實例:增加session屬性-session_attribute_add.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'session_attribute_add.jsp'startingpage</title></head>

<body><%session.setAttribute("hello","");%></body></html>當(dāng)?shù)谝淮螆?zhí)行本頁面時,將設(shè)置一個session屬性,此時Tomcat后臺輸出:D61F82CCEF27E882F8930429CC9EDAA4,增加屬性-->屬性名稱:hello,屬性內(nèi)容:當(dāng)重復(fù)執(zhí)行本頁面時,屬于替換屬性的操作,此時后臺輸出D61F82CCEF27E882F8930429CC9EDAA4,替換屬性-->屬性名稱:hello,屬性內(nèi)容:實例:刪除session屬性-session_attribute_remove.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'session_attribute_add.jsp'startingpage</title></head>

<body><%session.removeAttribute("hello");%></body></html>當(dāng)執(zhí)行本頁面時,將刪除hello屬性,此時后臺輸出D61F82CCEF27E882F8930429CC9EDAA4,刪除屬性-->屬性名稱:hello,屬性內(nèi)容:3.Session屬性監(jiān)聽-HttpSessionBindingListener接口之前講解過的session監(jiān)聽接口都需要在web.xml文件中配置后才可以其作用,但是在web中也提供了一個javax.servlet.http.HttpSessionBingdingListener接口,通過此接口實現(xiàn)的監(jiān)聽程序可以不用配置而直接使用。此接口定義的方法如下所示:No.方法類型描述1publicvoidvalueBound(HttpSessionBindingEventevent)普通綁定對象到session時觸發(fā)2publicvoidvalueUnbound(HttpSessionBindingEventevent)普通從session中移除對象時觸發(fā)上表中所列的兩個方法都將產(chǎn)生HttpSessionBindingEvent事件,此事件的方法已經(jīng)在表列出。實例:用戶登錄狀態(tài)監(jiān)聽-LoginUser.javapublicclassLoginUserimplementsHttpSessionBindingListener{privateStringname;publicLoginUser(Stringname){=name;}publicvoidvalueBound(HttpSessionBindingEventarg0){System.out.println("**在session中保存LoginUser對象name="+this.getName()+",sessionid"+arg0.getSession().getId());}publicvoidvalueUnbound(HttpSessionBindingEventarg0){System.out.println("**在session中移除LoginUser對象name="+this.getName()+",sessionid"+arg0.getSession().getId());}publicStringgetName(){returnname;}publicvoidsetName(Stringname){=name;}}實例:向session中增加LoginUser對象-session——bound.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><%@pageimport="com.xlh.demo.demo.*"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'session_attribute_add.jsp'startingpage</title></head>

<body>

<%LoginUseruser=newLoginUser("XLH");session.setAttribute("hello",user);

%></body></html>本程序首先實例化了一個LoginUser對象,然后將此對象保存在session屬性范圍中,程序運行如下:**在session中保存LoginUser對象name=XLH,sessionidD61F82CCEF27E882F8930429CC9EDAA4D61F82CCEF27E882F8930429CC9EDAA4,增加屬性-->屬性名稱:hello,屬性內(nèi)容:com.xlh.demo.demo.LoginUser@575e6691實例:從session中刪除LoginUser對象-session_unbound.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="GBK"%><%@pageimport="com.xlh.demo.demo.*"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><title>MyJSP'session_attribute_add.jsp'startingpage</title></head>

<body>

<%

session.removeAttribute("hello");

%></body></html>程序運行后,后臺輸出:**在session中移除LoginUser對象name=XLH,sessionidD61F82CCEF27E882F8930429CC9EDAA4D61F82CCEF27E882F8930429CC9EDAA4,刪除屬性-->屬性名稱:hello,屬性內(nèi)容:com.xlh.demo.demo.LoginUser@575e6691對request監(jiān)聽在Servlet2.4之后增加了對request操作的監(jiān)聽,主要使用ServletRequestListener和ServletRequestAttributeListener兩個接口。1.請求狀態(tài)監(jiān)聽:ServletRequestListener接口當(dāng)需要對用戶的每次請求進(jìn)行監(jiān)聽時,可以使用javax.servlet.ServletRequestListener接口,此接口定義的方法如下:No.方法類型描述1publicvoidrequestInitialized(ServletRequestEventsre)普通請求開始時調(diào)用2publicvoidrequestDestroyed(ServletRequestEventsre)普通請求結(jié)束時調(diào)用ServletRequestListener接口一旦監(jiān)聽到事件后,將產(chǎn)生ServletRequestEvent的事件處理對象,此事件定義的方法如下所示:No.方法類型描述1publicServletRequestgetServletRequest()普通取得ServletRequest對象2publicServletContextgetServletContext()普通取得ServletContext對象實例:對用戶請求request監(jiān)聽-ServletRequestListenerDemo.javapackagecom.xlh.demo.demo;publicclassServletRequestListenerDemoimplementsServletRequestListener{publicvoidrequestDestroyed(ServletRequestEventarg0){System.out.println("**reqeust銷毀。http://"+arg0.getServletRequest().getRemoteAddr()+arg0.getServletContext().getContextPath());}publicvoidrequestInitialized(ServletRequestEventarg0){System.out.println("**reqeust初始化。http://"+arg0.getServletRequest().getRemoteAddr()+arg0.getServletContext().getContextPath());}}實例:配置web.xml文件<listener><listener-class>com.xlh.demo.demo.ServletRequestListenerDemo</listener-class></listener>本程序?qū)⒈O(jiān)聽用戶的請求初始化和銷毀的操作,當(dāng)觸發(fā)監(jiān)聽時將打印請求的路徑。**reqeust初始化。**reqeust銷毀。2.Request屬性監(jiān)聽:ServletRequestAttributeListener接口對request范圍屬性的監(jiān)聽可以使用javax.servlet.ServletResquestAttributeListener接口,此接口定義的方法如下:No.方法類型描述1publicvoidattributeAdded(ServletRquestAttributeEventsrae)普通屬性增加時調(diào)用2publicvoidattributeRemoved(ServletRquestAttributeEventsrae)普通屬性刪除時調(diào)用3publicvoidattributeReplaced(ServletRquestAttributeEvents

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論