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

監(jiān)聽器(listener)

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

    • 監(jiān)聽器就是一個實現(xiàn)特定接口的普通java程序,這個程序?qū)iT用于監(jiān)聽另一個java對象的方法調(diào)用或?qū)傩愿淖?,?dāng)被監(jiān)聽對象發(fā)生上述事件后,監(jiān)聽器某個方法將立即被執(zhí)行。
    • 主要是用來監(jiān)聽特定對象的創(chuàng)建或銷毀、屬性的變化的!是一個實現(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)建和銷毀的時機
      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)建和銷毀的時機:
      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 方法進行相應(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)聽器的這個方法進行相應(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)聽器的這個方法進行相應(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. 實現(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上的過程,需要實現(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. 實現(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類,實現(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é) : 先寫類, 實現(xiàn)接口; 再配置

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

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

過濾器

  • 過濾器簡介 :

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

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

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

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

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

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

      • 寫一個普通java類,實現(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(); : 銷毀過濾器實例時候調(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)建實例
    public HelloFilter(){
        System.out.println("1. 創(chuàng)建過濾器實例");
    }
    @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ù)處理方法: 在請求到達servlet之前先進入此方法處理公用的業(yè)務(wù)邏輯操作
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("3. 執(zhí)行過濾器業(yè)務(wù)處理方法");
        // 放行 (去到Servlet)
        // 如果有下一個過濾器,進入下一個過濾器,否則就執(zhí)行訪問servlet
        chain.doFilter(request, response);
        
        System.out.println("5. Servlet處理完成,又回到過濾器");
    }
    @Override
    public void destroy() {
        System.out.println("6. 銷毀過濾器實例");
    }
}
  • 對指定的請求攔截
    • 默認攔截的類型:(直接訪問或者重定向 <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 確定一個項目創(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ū)間編碼、項目編碼、request/response、數(shù)據(jù)庫編碼一致

過濾器案例

  • 過濾器-編碼統(tǒng)一處理
    • 幾乎每一個Servlet都要涉及編碼處理:處理請求數(shù)據(jù)中文問題![GET/POST]
    • 每個servlet都要做這些操作,把公用的代碼抽取-過濾器實現(xiàn)!
    • 代碼實現(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中文亂碼,是因為在request.getParameter方法內(nèi)部沒有進行提交方式判斷并處理。
         * String name = request.getParameter("userName");
         * 
         * 解決:對指定接口的某一個方法進行功能擴展,可以使用代理!
         *      對request對象(目標(biāo)對象),創(chuàng)建代理對象!
         */
        HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
                request.getClass().getClassLoader(),        // 指定當(dāng)前使用的累加載器
                new Class[]{HttpServletRequest.class},      // 對目標(biāo)對象實現(xiàn)的接口類型
                new InvocationHandler() {                   // 事件處理器
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        // 定義方法返回值
                        Object returnValue = null;
                        // 獲取方法名
                        String methodName = method.getName();
                        // 判斷:對getParameter方法進行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ù)進行處理  (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ù)過濾

    • 模擬:論壇過濾敏感詞匯!
    • 實現(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)處理完: 下面進行無效數(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)到登陸!
  • 實現(xiàn)思路:

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

    1. 建庫、建表、建項目、引入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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容