servlet,filter, listener, interceptor 區別與聯繫

轉載自:http://www.cnblogs.com/zhhuanl/archive/2011/03/29/1998556.html
四種共同點:

對一類url,或所有url進行業務處理

對各種url之類進行匹配,查找,執行相應操作,與action相比較而言,action只能針對某一特定的url進行匹配,進行操作 如: <form action ="update.action"> action對應的url是固定的,對於struts1.x可能一個action只有一個url

對於struts2.0,一個action可能有多個url,看它實現的方法數量,不過這些url在提交之前都是已經的,固定的。而上面四種可以對任意url進行操作,如<url-pattern>*.action</url-pattern>

 

區別:1,servlet 流程是短的,url傳來之後,就對其進行處理,之後返回或轉向到某一自己指定的頁面。它主要用來在

     業務處理之前進行控制.

 2,filter 流程是線性的, url傳來之後,檢查之後,可保持原來的流程繼續向下執行,被下一個filter, servlet接收等,而servlet 處理之後,不會繼續向下傳遞。filter功能可用來保持流程繼續按照原來的方式進行下去,或者主導流程,而servlet的功能主要用來主導流程。

    filter可用來進行字符編碼的過濾,檢測用戶是否登陸的過濾,禁止頁面緩存等

 3,servlet,filter都是針對url之類的,而listener是針對對象的操作的,如session的創建,session.setAttribute的發生,在這樣的事件發生時做一些事情。

     可用來進行:Spring整合Struts,Strutsaction注入屬性,web應用定時任務的實現,在線人數的統計等

 

4interceptor 攔截器,類似於filter,不過在struts.xml中配置,不是在web.xml,並且不是針對URL的,而是針對action,當頁面提交action時,進行過濾操作,相當於struts1.x提供的plug-in機制,可以看作,前者是struts1.x自帶的filter,interceptor struts2 提供的filter.

    filter不同點:(1)不在web.xml中配置,而是在struts.xml中完成配置,與action在一起

                            ( 2  ) 可由action自己指定用哪個interceptor 來在接收之前做事

 

一,servlet

1, 在web.xml中配置

 Servlet

 <servlet>

<servlet-name>AutoServlet</servlet-name>

<servlet-class>

   com.servlet.AutoServlet

</servlet-class>

</servlet>

<servlet-mapping>

 <servlet-name>AutoServlet</servlet-name>

 <url-pattern>/AutoServlet</url-pattern>

</servlet-mapping>

2,定義AutoServlet,繼承HttpServlet,實現方法doGet, doPost

3, 應用:

1Struts1.x 就是一個Servlet, 它會在doGet方法中讀取配置文件struts-config.xml進行action的匹配,進行   業務處理

2)驗證碼生成(也可用action來做)

 

 

二,filter

1, web.xml配置

<filter>

<filter-name>checkUrl</filter-name>

<filter-class>com.lvjian.filter.CheckUrl</filter-class>

<init-param>

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

 <param-value>asong</param-value>   

                              //初始化傳參,得到時在filterinit方法中用filterConfig.getInitParameter("name" )

</init-param>

</filter>

<filter-mapping>

<filter-name>checkUrl</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

2, 繼承 javax.servlet.Filter,實現 doFilter(HttpServletRequestrequest, HttpServletResponse response

                                            FilterChain filterChain) 等方法 

 

     HttpServletRequest request = (HttpServletRequest) req;

     HttpServletResponse response = (HttpServletResponse) res;

     //獲取用戶請求的URI

    String request_uri = request.getRequestURI();

   //獲取web應用程序的上下文路徑

    String contextPath = request.getContextPath();

   //去除上下文路徑,得到剩餘部分的路徑

    String uri = request_uri.substring(contextPath.length());

    //創建會話session

   HttpSession session = request.getSession(true);

 

   //保持原有流程不變

    filterChain.doFilter( servletRequest , servletResponse );  

 

3,應用:(1Struts2.0

 

           (2) 進行字符編碼的過濾,檢測用戶是否登陸的過濾等

 

         3)禁止頁面緩存,原理就是對各個請求的url令其爲空,doFilter加入:

 

                  request.setCharacterEncoding("GB2312");//設置編碼

                  ((HttpServletResponse)response).setHeader("Pragma","No-cache");

                  ((HttpServletResponse)response).setHeader("Cache-Control","no-cache");

                  ((HttpServletResponse)response).setHeader("Expires","0");//禁止緩存

 

 

三,listener

 

1, 在web.xml中配置

 

  <listener>

      <listener-class>demo.listener.MyContextLoader</listener-class>

 </listener>

  //這樣服務器就會在啓動時創建MyContextLoader的一個實例,並開始監聽servlet,session的操作

2, 實現

 常用的listener有:

  1ServletContextListener 監聽ServletContext

       當創建ServletContext時,激發 contextInitialized(ServletContextEvent sce)方法;

      當銷燬ServletContext時,激發contextDestroyed(ServletContextEvent sce)方法。

 

  2ServletContextAttributeListener監聽對ServletContext屬性的操作,比如增加、刪除、修改屬性。

 

  3HttpSessionListener監聽HttpSession的操作。

         當創建一個Session時,激發 session Created(HttpSessionEvent se)方法;

         當銷燬一個Session時,激發sessionDestroyed (HttpSessionEvent se)方法。

 

 

 4HttpSessionAttributeListener監聽HttpSession中的屬性的操作。

       當在Session增加一個屬性時,激發 attributeAdded(HttpSessionBindingEvent se) 方法;

       當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEventse)方法;

       當在Session屬性被重新設置時,激發attributeReplaced(HttpSessionBindingEvent se) 方法。

 

 

 

 

 

四,interceptor

 

 

1, struts.xml中配置

 

創建一個strus.xml的子配置文件struts-l99-default.xml,它繼承與struts2struts-default,此配置文件是其他子配置文件的父類,只要是繼承與該文件的配置文件所聲明的路徑都會被它過濾 .

 

方法1. 普通配置法

 

<struts>

<package name="struts2"extends="struts-default">

<interceptors>

   <interceptor name="myInterceptor"class="edu.hust.interceptor.MyInterceptor"></interceptor>

</interceptors>

 

 

<action name="register"class="edu.hust.action.RegisterAction">

   <result name="input">/register.jsp</result>

   <result>/result.jsp</result>

 

   <!-- 在自定義interceptor並將其ref, 系統會覆蓋掉默認的interceptor-stack(defaultStack),爲了保證系統默認的defaultStack不受影響, 我們需要顯式的將其引入 -->

   <!-- 注意兩個interceptor-ref的順序, 順序不同, 執行效果也不同: 先配置的先執行/後配置的先退出(先進後出)-->

   <interceptor-refname="defaultStack"></interceptor-ref>

   <interceptor-refname="myInterceptor"></interceptor-ref>

</action>

</package>

</struts>

方法2. 配置攔截器棧(即將多個interceptor串聯的一種元素)。然後在<action>中引入該攔截器棧就可以了。

 

 執行順序爲先配置的先執行

 

 

  這樣做的原因是:多個action有相同的多個interceptor時,如一般自己寫一個,系統默認的有一個,要注入兩個,

 

對多個action都寫這兩個,不利於修改,可以寫成一個鏈,只需引用此鏈即可。

 

 

(1)攔截目標對象(被代理對象),這裏目標對象就是action(2)攔截器(一個類,動態的將某些方法插入到目標對象的某方法的beforeafter)(3)對目標對象生成的(動態)代理對象(代理對象內部方法綜合了目標對象方法+攔截器方法)。程序最終執行的是目標對象的代理,而這個代理已經插入了interceptor。攔截器作用:攔截actioninterceptor相當於一個入口和出口,通過interceptor進入action,執行完action的代碼再通過interceptor出去。針對"struts2 --interceptor(Interceptor怎麼寫)"這篇文章的MyInterceptor.classMyInterceptor2.class。根據下面的配置文件執行程序 <struts>    <packagename="struts2" extends="struts-default">       

<struts>

<package name="struts2"extends="struts-default">

 

<interceptors>

   <interceptor name="myInterceptor"class="edu.hust.interceptor.MyInterceptor"></interceptor>

 

   <interceptor-stack name="myInterceptorStack">

       <interceptor-refname="myInterceptor"></interceptor-ref>

       <interceptor-ref name="defaultStack"></interceptor-ref>

   </interceptor-stack>

</interceptors>

 

<action name="register"class="edu.hust.action.RegisterAction">

   <result name="input">/register.jsp</result>

   <result>/result.jsp</result>

 

   <interceptor-refname="myInterceptorStack"></interceptor-ref>

</action>

</package>

</struts>

方法3. 修改默認攔截器,將自定義的攔截器棧定義爲struts2的默認攔截器。

 

<struts>

<package name="struts2"extends="struts-default">

 

<interceptors>

   <interceptor name="myInterceptor"class="edu.hust.interceptor.MyInterceptor"></interceptor>

   <interceptor-stack name="myInterceptorStack">

       <interceptor-refname="myInterceptor"></interceptor-ref>

       <interceptor-refname="defaultStack"></interceptor-ref>

   </interceptor-stack>

</interceptors>

 

 

<!-- 此默認interceptor是針對當前包內所有action的,若不爲action顯式指定interceptor,就會用 default-interceptor-ref-->

<!-- 如果某個action中引入了interceptor, 則在這個action中此默認interceptor就會失效 -->

<default-interceptor-refname="myInterceptorStack"></default-interceptor-ref>

 

<action name="register"class="edu.hust.action.RegisterAction">

   <result name="input">/register.jsp</result>

   <result>/result.jsp</result>

</action>

 

</package>

</struts>

3. extends MethodFilterInterceptor的攔截器如何配置哪些方法該攔截、哪些方法不該攔截(針對方法攔截的配置)

 

<struts>

<package name="struts2"extends="struts-default">

 

<interceptors>

   <interceptor name="myInterceptor3"class="edu.hust.interceptor.MyInterceptor3"></interceptor>

</interceptors>

 

<action name="register"class="edu.hust.action.RegisterAction"method="queryAll">

   <result name="input">/register.jsp</result>

   <result>/result.jsp</result>

   <!-- myInterceptor3攔截器只對RegisterAction中的queryAll()方法和insert()方法進行了攔截, 其他方法未進行攔截 -->

   <interceptor-ref name="myInterceptor3">

       <param name="includeMethods">queryAll,execute</param>

   </interceptor-ref>

   <interceptor-refname="defaultStack"></interceptor-ref>

</action>

 

<action name="register"class="edu.hust.action.RegisterAction" method="insert">

   <result <span

2, 實現

interceptor類似於filter, 自定義filter是實現javax.servlet.Filter來完成,而interceptor類似,它通過實現com.opensymphony.xwork2.interceptor.Interceptor來自定義實現。

該接口提供了三個方法:

 

1)     void init(); 在該攔截器被初始化之後,在該攔截器執行攔截之前,系統回調該方法。對於每個攔截器而言,此方法只執行一次。

 

2)     void destroy();該方法跟init()方法對應。在攔截器實例被銷燬之前,系統將回調該方法。

 

3)     String intercept(ActionInvocation invocation) throws Exception; 該方法是用戶需要實現的攔截動作。該方法會返回一個字符串作爲邏輯視圖。

 

除此之外,繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor是更簡單的一種實現攔截器類的方式,因爲此類提供了init()destroy()方法的空實現,這樣我們只需要實現intercept方法。

 

 

 

 

3, 應用

 

 

 

import java.util.Map;

 

import com.opensymphony.xwork2.Action;

 

importcom.opensymphony.xwork2.ActionInvocation;

 

importcom.opensymphony.xwork2.interceptor.AbstractInterceptor;

 

/**

 

* 權限檢查攔截器

 

*

 

* @author qiujy

 

* @version 1.0

 

*/

 

public class AuthorizationInterceptorextends AbstractInterceptor {

 

/*

 

* 攔截Action處理的攔截方法

 

*

 

*/

 

public String intercept(ActionInvocationinvocation) throws

 

Exception {

 

 

 

 

//清除後臺頁面的緩存

HttpServletResponse response =ServletActionContext.getResponse();

 

 

 

// ServletActionContext 自動提供,可讓其獲得request,session,response

response.setHeader("Pragma","No-cache");

response.setHeader("Cache-Control","no-cache");

response.setHeader("Expires","0");

 

 

 

 

Map session =invocation.getInvocationContext().getSession();

String userName = (String)session.get("userName");

 

 

 

if (null != userName &&userName.equals("test")) {

 

   System.out.println("攔截器:合法用戶登錄---");

 

   return invocation.invoke(); //保持原來的流程不改變

 

} else {

 

   System.out.println("攔截器:用戶未登錄---");

 

    returnAction.LOGIN; //返回到配置文件中名字爲loginaction

 

}

 

}

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章