context-param 監聽器 過濾器 servlet 攔截器的區別

前言:一句話歸納啓動的順序html

context param上下文參數——>listener監聽器——>filter過濾器——>servlet——>intercept攔截器java

                    生命週期web

context-param上下文參數spring

當容器tomcat啓動的時候會讀取web.xml中的<context-param>標籤和<listener>標籤並初始化ServletContext(上下文)對象(ServletContext表明當前web項目,當前web項目中的全部內容都共享此對象)編程

而後容器tomcat將<context-param>中的內容解析爲鍵值對賦予ServletContext(這也就是爲何咱們能夠經過context-param的鍵得到context-param的值)瀏覽器

以後容器建立<listener></listener>中的類實例,即建立監聽器,在監聽中會有contextInitialized(ServletContextEvent args)初始化方法,經過在這個方法中的參數得到ServletContext = ServletContextEvent.getServletContext();緩存

最後獲得context-param的值 = ServletContext.getInitParameter("context-param的鍵");tomcat

listener監聽器獲得參數後就能夠進行換句話說,這個時候,對<context-param>中的鍵值對作的操做,將在的WEB項目徹底啓動以前被執行,常經過在web.xml中的配置來加載spring的配置文件服務器

<listener>
        <!-- 繼承於ServletContextListener,在tomcat啓動和關閉時會調用 -->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- 要讀取到servletContext容器中的spring配置文件的路徑 -->
        <param-value>classpath:ApplicationContext.xml</param-value>
</context-param>

 

listener監聽器session

根據執行的時機不一樣劃分,經常使用的監聽器一共有三類,都是繼承於父接口EventListener的子接口

ServletContextListener接口

  Tomcat啓動和關閉時調用的監聽器,也就是說在tomcat啓動時建立tomcat關閉時銷燬

  • public void contextInitialized(ServletContextEvent evt)ServletContext對象被建立後調用;
  • public void contextDestroyed(ServletContextEvent evt)ServletContext對象被銷燬前調用;

 HttpSessionListener接口

  開始會話和結束會話時調用的監聽器,也就是說開啓session時建立session失效時銷燬

  • public void sessionCreated(HttpSessionEvent evt)HttpSession對象被建立後調用;
  • public void sessionDestroyed(HttpSessionEvent evt)HttpSession對象被銷燬前調用;

  關於session失效有兩種狀況,一種是session.invalidate()方法註銷session,另外一種是超過了session的存活時間,tomcat中默認是30分鐘,能夠到tomcat/conf/web.xml文件中更改設置

 ServletRequestListener接口

  開始請求和結束請求時調用的監聽器,也就是說接收request請求時建立完成request請求後銷燬

  • public void requestInitiallized(ServletRequestEvent evt)ServletRequest對象被建立後調用;
  • public void requestDestroyed(ServletRequestEvent evt)ServletRequest對象被銷燬前調用。

 

filter過濾器

init(FilterConfig):在服務器啓動時會建立Filter實例而且每一個類型的Filter只建立一個實例,今後再也不建立!在建立完Filter實例後,會立刻調用init()方法完成初始化工做,這個方法只會被執行一次;

doFilter(ServletRequest req,ServletResponse res,FilterChain chain):這個方法會在用戶每次訪問指定過濾範圍時都會執行doFileter,若是須要「放行」,那麼須要調用FilterChain的doFilter(ServletRequest,ServletResponse)方法,若是不調用FilterChain的doFilter()方法,那麼目標資源將沒法執行;

destroy():服務器會在建立Filter對象以後,把Filter放到緩存中一直使用,一般不會銷燬它。通常會在服務器關閉時銷燬Filter對象,在銷燬Filter對象以前,服務器會調用Filter對象的destory()方法。

servlet

默認在第一次接受瀏覽器請求時建立servlet實例對象,在tomcat關閉時銷燬

javax.servlet.Servlet接口中,有三個方法說明了Servlet的生命週期:

void init(ServletConfig):建立後立刻調用init()完成初始化;

void service(ServletRequest,ServletResponse):每次處理請求時調用service()方法;

void destroy():當Tomcat要銷燬Servlet實例時,先調用destroy()方法;

能夠在web.xml文件中將servlet的建立時機改成和服務器同步

 interceptor攔截器

和過濾器相似,可是隻攔截用戶對action的請求,tomcat啓動時建立,攔截到用戶對action的請求時執行前置攔截器棧,放行後執行action邏輯並返回頁面視圖,最後再執行後置攔截器棧進行收尾工做

void init():建立後立刻調用init()完成初始化;

String intercept(ActionInvocation invocation):經過invocation.invoke()方法繼續執行攔截器棧中的其餘攔截器

void destroy():當Tomcat要銷燬Interceptor實例時,先調用destroy()方法;

前置攔截——>action——>頁面執行——>後置攔截

實際應用

過濾器filter 
過濾掉非法url(不是login.do的地址請求,若是用戶沒有登錄都過濾掉),或者在傳入servlet或者 struts的action前統一設置字符集, 或者去除掉一些非法字符(聊天室常常用到的,一些罵人的話)。

最經常使用的過濾器就是登錄過濾器LoginFilter,過濾器通常都是繼承Filter 接口

監聽器listener 
當你要觸發一個事件,但這件事既不是過濾,又不是攔截,那極可能就是監聽。 聯想到Windows編程裏的,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發送一個消息給應用程序。監聽器的概念相似於這些。

上下文參數context-param

用來存儲要應用在web項目全局中的參數

servlet

用來處理tomcat等容器解析後的請求

攔截器interceptor: 
進行權限驗證,或者是來判斷用戶是否登錄,日誌記錄,或者限制時間點訪問。我本身用過攔截器,是用戶每次登陸時,都能記錄一個登陸時間。 (這點用攔截器明顯合適,用過濾器明顯不合適,由於沒有過濾任何東西)

 

 

做用範圍

代碼和配置

context-param  要讀取到servletContext中的配置文件+web.xml配置

listener,filter,servlet  java類+web.xml配置

interceptor  java類+struts.xml配置

 

context-param上下文參數

context-param在web.xml文件中配置要讀取的xml文件路徑便可,通常都是讀取spring的ApplicationContext.xml文件

<listener>
        <!-- 繼承於ServletContextListener,在tomcat啓動和關閉時會調用 -->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- 要讀取到servletContext容器中的spring配置文件的路徑 -->
        <param-value>classpath:ApplicationContext.xml</param-value>
    </context-param>

listener監聽器

java類:根據監聽範圍需求的不一樣實現ServletContextListener或HttpSessionListener或ServletRequestListener三者之一

package com.rl.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * 自定義監聽器實現了ServletContextListener接口,也會在服務器啓動時初始化
 */
public class MyServletContextListener implements ServletContextListener {

    /**
     * 服務器中止時銷燬
     */
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("MyServletContextListener被銷燬");
    }
    
    /**
     * 服務器啓動時建立
     */
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("MyServletContextListener被建立");
        ServletContext sc = sce.getServletContext();
    }
}

配置listener:在web.xml文件中配置listener類的路徑便可

<listener>
        <!--指定做爲監聽器的類-->
    <listener-class>com.rl.listener.MyRequestListener</listener-class>
</listener>

filter過濾器

java類:做爲過濾器的類要實現Filter接口

package com.rl.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloFilter implements Filter {

    /**
     * 當服務器關閉當前方法被調用,實例被銷燬
     */
    public void destroy() {
        System.out.println("過濾器被銷燬...");
    }

    /**
     * 過濾器的執行方法
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("過濾器開始....");
        //讓過濾器往下走,放行,若是後面還有過濾器,那麼就執行下一個過濾器,若是是最後一個過濾器就去執行Controller
        chain.doFilter(request, response);
        System.out.println("過濾器結束....");
    }

    /**
     * 當服務器啓動的時候被執行,說明過濾器的實例是在服務器啓動時被建立的
     */
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("過濾器被建立...");
    }
}

配置filter:filter要在web.xml文件中配置filter類的路徑和filter過濾的範圍

 <filter>
      <filter-name>helloFilter</filter-name>
      <!--指定做爲過濾器的類-->
      <filter-class>com.rl.filter.HelloFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>helloFilter</filter-name>
      <!--過濾器過濾的範圍-->
      <url-pattern>/*</url-pattern>
  </filter-mapping>

servlet

java類:實現Servlet接口或繼承HttpServlet類(HttpServlet的父類GenericServlet實現了Servlet接口)

package com.rl.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * doGet是給get方式的http的請求作相應的
 * doPost是給post方式的http的請求作相應的
 */
public class HttpServletDemo extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("HttpServletDemo實例被建立了");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doGet方法被調用了");
        resp.getOutputStream().write("doGet方法被調用了".getBytes());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("doPost方法被調用了");
        doGet(req, resp);
    }
}

配置servlet:要在web.xml文件中配置servlet類的路徑和servlet的瀏覽器訪問路徑

<servlet>
      <!-- 設置servlet的名字 -->
      <servlet-name>helloServlet</servlet-name>
      <!-- 具體的servlet的類 -->
      <servlet-class>com.rl.servlet.ServletDemo1</servlet-class>
      <!-- 將servlet的啓動時機設置爲和服務器同步 -->
      <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
      <!-- 指定要映射 的servlet的名字 -->
      <servlet-name>helloServlet</servlet-name>
      <!-- servlet的具體映射路徑 -->
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>

interceptor過濾器

java類:做爲Interceptor攔截器的類要繼承於AbstractInterceptor類或繼承於MethodFilterInterceptor,要想排除對指定的action的攔截,就必定要繼承MethodFilterInterceptor類(它的父類也是AbstractInterceptor)

package com.rl.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyInterceptor extends AbstractInterceptor {
    @Override
    public void init() {
        System.out.println("建立攔截器");
    }
    @Override
    public void destroy() {
        System.out.println("銷燬攔截器");
    }
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("前置攔截執行....");
        //讓攔截器向下走而且返回結果代碼
        String result = invocation.invoke();
        System.out.println("後置攔截執行...");
        return result;
    }

}

要攔截的action類

package com.rl.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 擔當控制層的Action動做類
 */
public class PersonAction2 extends ActionSupport{

    public String savePerson(){
        System.out.println("新增Person");
        return super.SUCCESS;
    }
    
    public String deletePerson(){
        System.out.println("刪除Person");
        return super.SUCCESS;
    }
}

interceptor配置:牢記在interceptor標籤中,action要放在其餘標籤的後面,否則會報錯

<package name="testInterceptor" extends="struts-default" namespace="/person">
        <interceptors>
            <!-- 配置咱們本身的攔截器 -->
            <interceptor name="myInterceptor" class="com.rl.interceptor.MyInterceptor"></interceptor>
            <!-- 配置咱們本身的攔截器棧 -->
            <interceptor-stack name="myStack">
                <!-- 默認的攔截器棧 -->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="myInterceptor"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 包內默認攔截器棧設置爲咱們本身的myStack -->
        <default-interceptor-ref name="myStack"></default-interceptor-ref>
        <action name="*" class="com.rl.action.PersonAction2" method="{1}Person">
            <result name="success">/success.jsp</result>
        </action>
    </package>

參考連接:

過濾器,攔截器,監聽器具體應用上的區別 - 阿里雲  https://yq.aliyun.com/ziliao/365762

session會話過時時間設置 https://blog.csdn.net/zqd_java/article/details/53687954

web.xml的配置中<context-param>配置做用 https://www.cnblogs.com/jiaguozhilian/p/5819032.html

struts.xml文件中package標籤中的子標籤順序 https://blog.csdn.net/lc448986375/article/details/8027150

servlet百度百科 https://baike.baidu.com/item/servlet/477555?fr=aladdin

相關文章
相關標籤/搜索