監(jiān)聽器/過濾器(Servlet Listener / Filter)

監(jiān)聽器(listener)

  • 監(jiān)聽器簡介 :

    • 監(jiān)聽器就是一個實(shí)現(xiàn)特定接口的普通java程序浆兰,這個程序?qū)iT用于監(jiān)聽另一個java對象的方法調(diào)用或?qū)傩愿淖兛慕觯?dāng)被監(jiān)聽對象發(fā)生上述事件后,監(jiān)聽器某個方法將立即被執(zhí)行簸呈。
    • 主要是用來監(jiān)聽特定對象的創(chuàng)建或銷毀榕订、屬性的變化的!是一個實(shí)現(xiàn)特定接口的普通java類蜕便!
    • 對象:自己創(chuàng)建自己用 (不用監(jiān)聽), 別人創(chuàng)建自己用 (需要監(jiān)聽)
  • 監(jiān)聽器的監(jiān)聽對象

    • 在Servlet規(guī)范中定義了多種類型的監(jiān)聽器劫恒,它們用于監(jiān)聽的事件源分別為ServletContext, HttpSessionServletRequest 這三個域?qū)ο?/li>
    • Servlet規(guī)范針對這三個對象上的操作,又把這多種類型的監(jiān)聽器劃分為三種類型
      1. 監(jiān)聽三個域?qū)ο髣?chuàng)建和銷毀的事件監(jiān)聽器
      2. 監(jiān)聽域?qū)ο笾袑傩缘脑黾雍蛣h除的事件監(jiān)聽器
      3. 監(jiān)聽綁定到 HttpSession 域中的某個對象的狀態(tài)的事件監(jiān)聽器 (查看API文檔)
  • 監(jiān)聽器接口
    一轿腺、監(jiān)聽對象創(chuàng)建/銷毀的監(jiān)聽器接口

    1. 監(jiān)聽ServletContext域?qū)ο髣?chuàng)建和銷毀
    - ServletContextListener 接口用于監(jiān)聽 ServletContext 對象的創(chuàng)建和銷毀事件两嘴。
    - 當(dāng) ServletContext 對象被創(chuàng)建時,激發(fā)contextInitialized (ServletContextEvent sce)方法
    - 當(dāng) ServletContext 對象被銷毀時族壳,激發(fā)contextDestroyed(ServletContextEvent sce)方法憔辫。
    - servletContext域?qū)ο蠛螘r創(chuàng)建和銷毀:
      1. 創(chuàng)建:服務(wù)器啟動針對每一個web應(yīng)用創(chuàng)建servletcontext
      2. 銷毀:服務(wù)器關(guān)閉前先關(guān)閉代表每一個web應(yīng)用的servletContext
    
    1. 監(jiān)聽HttpSession域?qū)ο髣?chuàng)建和銷毀
    - HttpSessionListener接口用于監(jiān)聽HttpSession的創(chuàng)建和銷毀
    - 創(chuàng)建一個Session時,sessionCreated(HttpSessionEvent se) 方法將會被調(diào)用
    - 銷毀一個Session時仿荆,sessionDestroyed (HttpSessionEvent se) 方法將會被調(diào)用(此處復(fù)習(xí)session對象螺垢,寫多個servlet都去getSession,看session的創(chuàng)建)
    - Session域?qū)ο髣?chuàng)建和銷毀的時機(jī)
      1. 創(chuàng)建:用戶每一次訪問時赖歌,服務(wù)器創(chuàng)建session
      2. 銷毀:如果用戶的session 30分鐘沒有使用枉圃,服務(wù)器就會銷毀session,我們在web.xml里面也可以配置session失效時間
    
    1. 監(jiān)聽HttpRequest域?qū)ο髣?chuàng)建和銷毀
    - ServletRequestListener 接口用于監(jiān)聽ServletRequest 對象的創(chuàng)建和銷毀
    - Request 對象被創(chuàng)建時庐冯,監(jiān)聽器的requestInitialized方法將會被調(diào)用
    - Request對象被銷毀時孽亲,監(jiān)聽器的requestDestroyed方法將會被調(diào)用(此處復(fù)習(xí)request對象,在瀏覽器窗口中多次刷新訪問servlet展父,看request對象的創(chuàng)建和銷毀返劲,并寫一個servlet,然后用sendRedirect栖茉、forward方式跳轉(zhuǎn)到其它servlet,查看request對象的創(chuàng)建和消耗)
    - servletRequest域?qū)ο髣?chuàng)建和銷毀的時機(jī):
      1. 創(chuàng)建:用戶每一次訪問吕漂,都會創(chuàng)建一個reqeust
      2. 銷毀:當(dāng)前訪問結(jié)束亲配,request對象就會銷毀
    
    1. 代碼 :
    - ServletRequestListener(監(jiān)聽request對象的創(chuàng)建或銷毀)
    
package anderson.sh.life;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
// 監(jiān)聽request對象的創(chuàng)建或銷毀
public class MyRequestListener implements ServletRequestListener{
   // 對象銷毀
   @Override
   public void requestDestroyed(ServletRequestEvent sre) {
       // 獲取request中存放的數(shù)據(jù)
       Object obj = sre.getServletRequest().getAttribute("cn");
       System.out.println(obj);
       System.out.println("MyRequestListener.requestDestroyed()");
   }
   // 對象創(chuàng)建
   @Override
   public void requestInitialized(ServletRequestEvent sre) {
       System.out.println("MyRequestListener.requestInitialized()");
   }
}
  - HttpSessionListener(監(jiān)聽session對象的創(chuàng)建或銷毀)
package anderson.sh.life;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
監(jiān)聽Session對象創(chuàng)建、銷毀
 */
public class MySessionListener implements HttpSessionListener{
    // 創(chuàng)建
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("MySessionListener.sessionCreated()");
    }
    // 銷毀
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("MySessionListener.sessionDestroyed()");
    }
}
  - ServletContextListener(監(jiān)聽servletContext對象的創(chuàng)建或銷毀)
package anderson.sh.life;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
監(jiān)聽ServletContext對象創(chuàng)建或銷毀
 */
public class MyServletContextListener implements ServletContextListener{
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("MyServletContextListener.contextDestroyed()");
    }
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("1..........MyServletContextListener.contextInitialized()");
    }
}

二、監(jiān)聽對象屬性的變化
- Servlet規(guī)范定義了監(jiān)聽 ServletContext, HttpSession, HttpServletRequest 這三個對象中的屬性變更信息事件的監(jiān)聽器, 這三個監(jiān)聽器接口分別是ServletContextAttributeListener, HttpSessionAttributeListener ServletRequestAttributeListener, 這三個接口中都定義了三個方法來處理被監(jiān)聽對象中的屬性的增加吼虎,刪除和替換的事件犬钢,同一個事件在這三個接口中對應(yīng)的方法名稱完全相同,只是接受的參數(shù)類型不同

- attributeAdded 方法
  - 當(dāng)向被監(jiān)聽器對象中增加一個屬性時思灰,web容器就調(diào)用事件監(jiān)聽器的 attributeAdded 方法進(jìn)行相應(yīng)玷犹,這個方法接受一個事件類型的參數(shù),監(jiān)聽器可以通過這個參數(shù)來獲得正在增加屬性的域?qū)ο蠛捅槐4娴接蛑械膶傩詫ο?  - 各個域?qū)傩员O(jiān)聽器中的完整語法定義為:
    1. `` public void attributeAdded(ServletContextAttributeEvent scae) ``
    2. `` public void attributeReplaced(HttpSessionBindingEvent  hsbe) ``
    3. `` public void attributeRmoved(ServletRequestAttributeEvent srae) ``

- attributeRemoved 方法
  - 當(dāng)刪除被監(jiān)聽對象中的一個屬性時洒疚,web 容器調(diào)用事件監(jiān)聽器的這個方法進(jìn)行相應(yīng)
  - 各個域?qū)傩员O(jiān)聽器中的完整語法定義為:
    1. `` public void attributeRemoved(ServletContextAttributeEvent scae) ``
    2. `` public void attributeRemoved (HttpSessionBindingEvent** ** hsbe) ``
    3. `` public void attributeRemoved (ServletRequestAttributeEvent srae) ``

- attributeReplaced 方法
  - 當(dāng)監(jiān)聽器的域?qū)ο笾械哪硞€屬性被替換時歹颓,web容器調(diào)用事件監(jiān)聽器的這個方法進(jìn)行相應(yīng)各個域?qū)傩员O(jiān)聽器中的完整語法定義為:
    1. `` public void attributeReplaced(ServletContextAttributeEvent scae) ``
    2. `` public void attributeReplaced (HttpSessionBindingEvent** ** hsbe) `` 
    3. `` public void attributeReplaced (ServletRequestAttributeEvent srae) ``

- 代碼: 
package anderson.sh.attr;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/** 
監(jiān)聽session對象屬性的變化
 */
public class MySessionAttrListener implements HttpSessionAttributeListener {
    // 屬性添加
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        // 先獲取session對象
        HttpSession session = se.getSession();
        // 獲取添加的屬性
        Object obj = session.getAttribute("userName");
        // 測試
        System.out.println("添加的屬性:" + obj);
    }
    // 屬性移除
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("屬性移除");
    }
    // 屬性被替換
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        // 獲取sesison對象
        HttpSession session = se.getSession();
        // 獲取替換前的值
        Object old = se.getValue();
        System.out.println("原來的值:" + old);
        // 獲取新值
        Object obj_new = session.getAttribute("userName");
        System.out.println("新值:" + obj_new);
    }
}

三、session相關(guān)監(jiān)聽器(HttpSessionBindingListener)
- HttpSessionBindingListener : 監(jiān)聽對象綁定到session上的事件 (監(jiān)聽對象綁定/解除綁定到sesison上的事件! )
1. 實(shí)現(xiàn)了HttpSessionBindingListener接口的 JavaBean 對象可以感知自己被綁定到 Session 中和從 Session 中刪除的事件
2. 當(dāng)對象被綁定到 HttpSession 對象中時油湖,web服務(wù)器調(diào)用該對象的 void valueBound(HttpSessionBindingEvent event) 方法
3. 當(dāng)對象從 HttpSession 對象中解除綁定時晴股,web服務(wù)器調(diào)用該對象的 void valueUnbound(HttpSessionBindingEvent event) 方法
4. 代碼

package anderson.sh.session;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
// 監(jiān)聽此對象綁定到session上的過程,需要實(shí)現(xiàn)session特定接口
public class Admin implements HttpSessionBindingListener {
  private int id;
  private String name;
  public Admin() {
      super();
  }
  public Admin(int id, String name) {
      super();
      this.id = id;
      this.name = name;
  }
  // 構(gòu)造函數(shù)
  public int getId() {
      return id;
  }
  public void setId(int id) {
      this.id = id;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  // 對象放入session
  @Override
  public void valueBound(HttpSessionBindingEvent event) {
      System.out.println("Admin對象已經(jīng)放入session");
  }
  // 對象從session中移除
  @Override
  public void valueUnbound(HttpSessionBindingEvent event) {
      System.out.println("Admin對象從session中移除肺魁!");
  }
}
- HttpSessionActivationListener(了解) 監(jiān)聽session序列化及反序列化的事件
  1. 實(shí)現(xiàn)了HttpSessionActivationListener接口的 JavaBean 對象可以感知自己被活化和鈍化的事件
  2. 當(dāng)綁定到 HttpSession 對象中的對象將要隨 HttpSession 對象被鈍化之前电湘,web 服務(wù)器調(diào)用如下方法 `` sessionWillPassivate(HttpSessionBindingEvent event) `` 方法
  3. 當(dāng)綁定到 HttpSession 對象中的對象將要隨 HttpSession 對象被活化之后,web 服務(wù)器調(diào)用該對象的 `` void sessionDidActive(HttpSessionBindingEvent event) ``方法
  • 生命周期監(jiān)聽器
    • 聲明周期監(jiān)聽器: 監(jiān)聽對象的創(chuàng)建鹅经、銷毀的過程寂呛!
      • 監(jiān)聽器開發(fā)步驟:
        1. 寫一個普通java類,實(shí)現(xiàn)相關(guān)接口瘾晃;
        2. 配置(web.xml)
<!-- session的最大活躍時間 -->
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
    <!-- 監(jiān)聽request對象創(chuàng)建贷痪、銷毀 -->
    <listener>
        <listener-class>cn.itcast.a_life.MyRequestListener</listener-class>
    </listener>
    <!-- 監(jiān)聽session對象創(chuàng)建、銷毀 -->
    <listener>
        <listener-class>cn.itcast.a_life.MySessionListener</listener-class>
    </listener>
    <!-- 監(jiān)聽servletContext對象創(chuàng)建蹦误、銷毀 -->
    <listener>
        <listener-class>cn.itcast.a_life.MyServletContextListener</listener-class>
    </listener>
    <!-- 屬性監(jiān)聽器 -->
    <listener>
        <listener-class>cn.itcast.b_attr.MySessionAttrListener</listener-class>
    </listener>
  • 404(路徑寫錯); 500(服務(wù)器錯誤,調(diào)試)

  • 屬性監(jiān)聽器

    • 監(jiān)聽:request/session/servletContext對象屬性的變化强胰!
      • ServletRequestAttributeListener
      • HttpSessionAttributeListener
      • ServletContextAttributeListener
  • 總結(jié) : 先寫類, 實(shí)現(xiàn)接口; 再配置

  • 其他監(jiān)聽器 : session相關(guān)監(jiān)聽器

    • 步驟 : 對象實(shí)現(xiàn)接口; 再把對象綁定/解除綁定到session上就會觸發(fā)監(jiān)聽代碼
    • 作用 : ( 上線提醒 )
    • 思考 : 這個session監(jiān)聽器偶洋,和上面的聲明周期牵寺、屬性監(jiān)聽器區(qū)別恩脂?
      • 不用再web.xml配置
      • 因?yàn)楸O(jiān)聽的對象是自己創(chuàng)建的對象黎休,不是服務(wù)器對象!

過濾器

  • 過濾器簡介 :

    • Filter也稱為過濾器,它是Servlet技術(shù)中最激動人心的技術(shù)嫉鲸,WEB開發(fā)人員通過Filter技術(shù)玄渗,對web服務(wù)器管理的所有web資源:例如Jsp, Servlet, 靜態(tài)圖片文件或靜態(tài) html 文件等進(jìn)行攔截藤树,從而實(shí)現(xiàn)一些特殊的功能。例如實(shí)現(xiàn)URL級別的權(quán)限訪問控制屡限、過濾敏感詞匯炕倘、壓縮響應(yīng)信息等一些高級功能啊央。

    • Servlet API中提供了一個Filter接口瓜饥,開發(fā)web應(yīng)用時压固,如果編寫的Java類實(shí)現(xiàn)了這個接口帐我,則把這個java類稱之為過濾器Filter拦键。通過Filter技術(shù)萄金,開發(fā)人員可以實(shí)現(xiàn)用戶在訪問某個目標(biāo)資源之前氧敢,對訪問的請求和響應(yīng)進(jìn)行攔截

    • Filter是如何實(shí)現(xiàn)攔截的?

      • Filter接口中有一個doFilter方法孙乖,當(dāng)開發(fā)人員編寫好Filter,并配置對哪個web資源進(jìn)行攔截后蜗帜,WEB服務(wù)器每次在調(diào)用web資源的service方法之前蔬顾,都會先調(diào)用一下filter的doFilter方法湘捎,因此消痛,在該方法內(nèi)編寫代碼可達(dá)到如下目的:
        • 調(diào)用目標(biāo)資源前秩伞,讓一段代碼先執(zhí)行
        • 是否調(diào)用目標(biāo)資源(即是否讓用戶訪問web資源)
          • web服務(wù)器在調(diào)用doFilter方法時展氓,會傳遞一個filterChain對象進(jìn)來遇汞,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法歪赢,開發(fā)人員可以根據(jù)需求決定是否調(diào)用此方法埋凯,調(diào)用該方法白对,則web服務(wù)器就會調(diào)用web資源的service方法蟀瞧,即web資源就會被訪問黄橘,否則web資源不會被訪問。
        • 調(diào)用目標(biāo)資源之后子巾,讓一段代碼執(zhí)行
    • 為什么需用到過濾器 : 項(xiàng)目開發(fā)中,經(jīng)常會涉及到重復(fù)代碼的實(shí)現(xiàn)仪搔!

    • 過濾器烤咧,設(shè)計執(zhí)行流程:(OOAD : 面向?qū)ο蟮姆治雠c設(shè)計 - 時序圖)

      1. 用戶訪問服務(wù)器
      2. 過濾器: 對Servlet請求進(jìn)行攔截
      3. 先進(jìn)入過濾器煮嫌, 過濾器處理
      4. 過濾器處理完后, 在放行抱虐, 此時昌阿,請求到達(dá)Servlet/JSP
      5. Servlet處理
      6. Servlet處理完后,再回到過濾器, 最后在由tomcat服務(wù)器相應(yīng)用戶恳邀;
    • 開發(fā)步驟 :

      • 寫一個普通java類懦冰,實(shí)現(xiàn)Filter接口
      • 配置過濾器
  • 過濾器相關(guān)Api

    • interface Filter : 過濾器核心接口
      1. Void init(filterConfig); : 初始化方法,在服務(wù)器啟動時候執(zhí)行
      2. Void doFilter(request,response,filterChain); : 過濾器攔截的業(yè)務(wù)處理方法
      3. Void destroy(); : 銷毀過濾器實(shí)例時候調(diào)用
    • interface FilterConfig : 獲取初始化參數(shù)信息
    • interface FilterChain : 過濾器鏈參數(shù)谣沸;一個個過濾器形成一個執(zhí)行鏈儿奶;
      1. void doFilter(ServletRequest request, ServletResponse response); : 執(zhí)行下一個過濾器或放行
package cn.itcast.a_filter_hello;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// 過濾器,測試@author Jie.Yuan
public class HelloFilter implements Filter{
    // 創(chuàng)建實(shí)例
    public HelloFilter(){
        System.out.println("1. 創(chuàng)建過濾器實(shí)例");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2. 執(zhí)行過濾器初始化方法");
        // 獲取過濾器在web.xml中配置的初始化參數(shù)
        String encoding = filterConfig.getInitParameter("encoding");
        System.out.println(encoding);
        // 獲取過濾器在web.xml中配置的初始化參數(shù) 的名稱
        Enumeration<String> enums =  filterConfig.getInitParameterNames();
        while (enums.hasMoreElements()){
            // 獲取所有參數(shù)名稱:encoding鳄抒、path
            String name = enums.nextElement();
            // 獲取名稱對應(yīng)的值
            String value = filterConfig.getInitParameter(name);
            System.out.println(name + "\t" + value);
        }
    }
    // 過濾器業(yè)務(wù)處理方法: 在請求到達(dá)servlet之前先進(jìn)入此方法處理公用的業(yè)務(wù)邏輯操作
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("3. 執(zhí)行過濾器業(yè)務(wù)處理方法");
        // 放行 (去到Servlet)
        // 如果有下一個過濾器闯捎,進(jìn)入下一個過濾器,否則就執(zhí)行訪問servlet
        chain.doFilter(request, response);
        
        System.out.println("5. Servlet處理完成茬祷,又回到過濾器");
    }
    @Override
    public void destroy() {
        System.out.println("6. 銷毀過濾器實(shí)例");
    }
}
  • 對指定的請求攔截
    • 默認(rèn)攔截的類型:(直接訪問或者重定向 <dispatcher>REQUEST</dispatcher>
    • 攔截轉(zhuǎn)發(fā) : <dispatcher>FORWARD</dispatcher>
    • 攔截包含的頁面(RequestDispatcher.include(/page.jsp); 對page.jsp也執(zhí)行攔截<dispatcher>INCLUDE</dispatcher>
    • 攔截聲明式異常信息 : <dispatcher>ERROR</dispatcher>
  • 共性問題:
    1. 過濾器 : 方法參數(shù)沒有自動命名粥惧,說明沒有關(guān)聯(lián)源碼-> 關(guān)聯(lián)tomcat或servlet源代碼
    2. 連接池 : 多刷新幾次咏删,報錯!
      1. 連接沒關(guān) :
        QueryRunner qr = new QueryRunner();
        qr.update(con,sql);// 這里con一定要關(guān)閉
      2. 注意:dataSource 確定一個項(xiàng)目創(chuàng)建一次 : QueryRunner qr = new QueryRunner(dataSource);
        3.修改連接池參數(shù)配置
    3. 編碼
    • request.setCharacterEncoding("UTF-8"); // 設(shè)置POST提交的請求的編碼
    • response.setCharacterEncoding("UTF-8"); // 設(shè)置相應(yīng)體的編碼
    • response.setContentType("text/html;charset=UTF-8"); // 設(shè)置頁面打開時候時候的編碼格式、 設(shè)置相應(yīng)體的編碼
    1. 開發(fā)中 : 工作區(qū)間編碼、項(xiàng)目編碼、request/response、數(shù)據(jù)庫編碼一致

過濾器案例

  • 過濾器-編碼統(tǒng)一處理
    • 幾乎每一個Servlet都要涉及編碼處理:處理請求數(shù)據(jù)中文問題司倚![GET/POST]
    • 每個servlet都要做這些操作鸵鸥,把公用的代碼抽取-過濾器實(shí)現(xiàn)!
    • 代碼實(shí)現(xiàn)思路:
      • Login.jsp : 登陸,輸入“中文”
      • LoginServlet.java : 直接處理登陸請求
      • EncodingFilter.java : 過濾器處理請求數(shù)據(jù)編碼:GET/POST
// 過濾器 : 編碼處理統(tǒng)一寫到這里(servlet中不需要再處理編碼)
public class EncodingFilter implements Filter {
    // 過濾器業(yè)務(wù)處理方法:處理的公用的業(yè)務(wù)邏輯操作
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        // 轉(zhuǎn)型
        final HttpServletRequest request = (HttpServletRequest) req;    
        HttpServletResponse response = (HttpServletResponse) res;
        
        // 一、處理公用業(yè)務(wù)
        request.setCharacterEncoding("UTF-8");                  // POST提交有效
        response.setContentType("text/html;charset=UTF-8");
        
        /*
         * 出現(xiàn)GET中文亂碼唱较,是因?yàn)樵趓equest.getParameter方法內(nèi)部沒有進(jìn)行提交方式判斷并處理倍阐。
         * String name = request.getParameter("userName");
         * 
         * 解決:對指定接口的某一個方法進(jìn)行功能擴(kuò)展尽纽,可以使用代理!
         *      對request對象(目標(biāo)對象),創(chuàng)建代理對象危尿!
         */
        HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
                request.getClass().getClassLoader(),        // 指定當(dāng)前使用的累加載器
                new Class[]{HttpServletRequest.class},      // 對目標(biāo)對象實(shí)現(xiàn)的接口類型
                new InvocationHandler() {                   // 事件處理器
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        // 定義方法返回值
                        Object returnValue = null;
                        // 獲取方法名
                        String methodName = method.getName();
                        // 判斷:對getParameter方法進(jìn)行GET提交中文處理
                        if ("getParameter".equals(methodName)) {
                            
                            // 獲取請求數(shù)據(jù)值【 <input type="text" name="userName">】
                            String value = request.getParameter(args[0].toString());    // 調(diào)用目標(biāo)對象的方法
                            
                            // 獲取提交方式
                            String methodSubmit = request.getMethod(); // 直接調(diào)用目標(biāo)對象的方法
                            
                            // 判斷如果是GET提交,需要對數(shù)據(jù)進(jìn)行處理  (POST提交已經(jīng)處理過了)
                            if ("GET".equals(methodSubmit)) {
                                if (value != null && !"".equals(value.trim())){
                                    // 處理GET中文
                                    value = new String(value.getBytes("ISO8859-1"),"UTF-8");
                                }
                            } 
                            return value;
                        }else {
                            // 執(zhí)行request對象的其他方法
                            returnValue = method.invoke(request, args);
                        }
                        return returnValue;
                    }
});
            // 二、放行 (執(zhí)行下一個過濾器或者servlet)
        chain.doFilter(proxy, response);  // 傳入代理對象
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {   
    }
    @Override
    public void destroy() {
    }
}
過濾器配置:
<!-- 編碼處理過濾器配置 -->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>cn.itcast.a_loginFilter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
public class LoginServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 獲取請求數(shù)據(jù) 
        String name = request.getParameter("userName");
        System.out.println("用戶:" + name);
    }
  • 過濾器-無效數(shù)據(jù)過濾

    • 模擬:論壇過濾敏感詞匯!
    • 實(shí)現(xiàn)思路:
      • Dis.jsp : 討論區(qū)頁面
      • DisServlet.java : 處理提交
        • 獲取請求參數(shù)
        • 保存到request域
        • 跳轉(zhuǎn)dis.jsp 【從request取數(shù)據(jù)顯示(處理后)】
      • DataFilter.java : 過濾器
        • 編碼
        • 無效數(shù)據(jù)處理
          即: 在上一個案例基礎(chǔ)上,再添加無效數(shù)據(jù)過濾的相關(guān)代碼!
  • JSP引入ckeditor組件:客戶端組件,便于用戶輸入內(nèi)容!

    • jsp :
<!-- 引入ckeditor組件(給用戶輸入提供方便) --> 
    <script src="${pageContext.request.contextPath }/ckeditor/ckeditor.js"></script>
    <link rel="stylesheet" href="${pageContext.request.contextPath }/ckeditor/samples/sample.css">
<body>
    ${requestScope.content }
    <form name="frmDis" action="${pageContext.request.contextPath }/dis" method="post">
      發(fā)表評論: <textarea class="ckeditor" rows="6" cols="30" name="content"></textarea>
      <br/>
      <input type="submit" value="評論" >
    </form>
  </body>
  • Filter:
// 在上個過濾器案例的基礎(chǔ)上蛮穿,增加如下代碼:
// 中文數(shù)據(jù)已經(jīng)處理完: 下面進(jìn)行無效數(shù)據(jù)過濾   
//【如何value中出現(xiàn)dirtyData中數(shù)據(jù),用****替換】  
for (String data : dirtyData) {
// 判斷當(dāng)前輸入數(shù)據(jù)(value), 是否包含無效數(shù)據(jù)
      if (value.contains(data)){
          value = value.replace(data, "*****");
      }
}
  • 登陸權(quán)限判斷

  • 登陸毁渗, 提交到登陸Servlet處理其業(yè)務(wù)践磅!

    • 登陸成功, 跳轉(zhuǎn)到首頁,顯示歡迎信息 + 列表信息
    • 登陸失敗祝蝠,跳轉(zhuǎn)到登陸音诈!
  • 要求:

    • 只有登陸后幻碱,才可以訪問首頁, 顯示列表
    • 如果沒有登陸绎狭,直接訪問首頁列表,要跳轉(zhuǎn)到登陸!
  • 實(shí)現(xiàn)思路:

    • Login.jsp : 登陸頁面
    • List.jsp : 列表顯示
    • LoginServlet.java : 登陸處理servlet
    • IndexServlet.java : 首頁列表查詢Servlet
    • LoginFilter.java : 登陸驗(yàn)證過濾器
      (用之前的表 : admin存儲登陸用戶, 登陸用employee 存儲員工信息褥傍,列表顯示用儡嘶!)
  • 實(shí)現(xiàn)步驟:

    1. 建庫、建表恍风、建項(xiàng)目蹦狂、引入jar文件
    2. entity
    • Admin.java
    • Employee.java
    1. Dao
    • AdminDao
    • EmployeeDao
    1. Servcie
    2. Servlet
  • 注意 : 網(wǎng)站訪問

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朋贬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖餐曹,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馆纳,死亡現(xiàn)場離奇詭異,居然都是意外死亡糠亩,警方通過查閱死者的電腦和手機(jī)虐骑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門准验,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廷没,你說我怎么就攤上這事糊饱。” “怎么了颠黎?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵另锋,是天一觀的道長。 經(jīng)常有香客問我狭归,道長砰蠢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任唉铜,我火速辦了婚禮台舱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潭流。我一直安慰自己竞惋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布灰嫉。 她就那樣靜靜地躺著拆宛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讼撒。 梳的紋絲不亂的頭發(fā)上浑厚,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音根盒,去河邊找鬼钳幅。 笑死,一個胖子當(dāng)著我的面吹牛炎滞,可吹牛的內(nèi)容都是我干的敢艰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼册赛,長吁一口氣:“原來是場噩夢啊……” “哼钠导!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起森瘪,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牡属,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扼睬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逮栅,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了证芭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞳浦。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖废士,靈堂內(nèi)的尸體忽然破棺而出叫潦,到底是詐尸還是另有隱情,我是刑警寧澤官硝,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布矗蕊,位于F島的核電站,受9級特大地震影響氢架,放射性物質(zhì)發(fā)生泄漏傻咖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一岖研、第九天 我趴在偏房一處隱蔽的房頂上張望卿操。 院中可真熱鬧,春花似錦孙援、人聲如沸害淤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窥摄。三九已至,卻和暖如春础淤,著一層夾襖步出監(jiān)牢的瞬間崭放,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工鸽凶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留币砂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓吱瘩,卻偏偏與公主長得像道伟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子使碾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Servlet過濾器是 Servlet 程序的一種特殊用法,主要用來完成一些通用的操作祝懂,如編碼的過濾票摇、判斷用戶的登...
    重山楊閱讀 1,229評論 0 12
  • 僅作為自己學(xué)習(xí)記錄使用,文章來自: 1砚蓬、http://blog.csdn.net/csh624366188/art...
    BakerZhang閱讀 1,015評論 1 5
  • 目標(biāo) servlet的生命周期 servletConfig與ServletContext定義矢门,及其二者的區(qū)別 監(jiān)聽...
    arkulo閱讀 970評論 0 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器祟剔,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 本文包括:1隔躲、Filter簡介2、Filter是如何實(shí)現(xiàn)攔截的物延?3宣旱、Filter開發(fā)入門4、Filter的生命周期...
    廖少少閱讀 7,276評論 3 56