監(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
,HttpSession
和ServletRequest
這三個域?qū)ο?/li> - Servlet規(guī)范針對這三個對象上的操作,又把這多種類型的監(jiān)聽器劃分為三種類型
- 監(jiān)聽三個域?qū)ο髣?chuàng)建和銷毀的事件監(jiān)聽器
- 監(jiān)聽域?qū)ο笾袑傩缘脑黾雍蛣h除的事件監(jiān)聽器
- 監(jiān)聽綁定到 HttpSession 域中的某個對象的狀態(tài)的事件監(jiān)聽器 (查看API文檔)
- 在Servlet規(guī)范中定義了多種類型的監(jiān)聽器劫恒,它們用于監(jiān)聽的事件源分別為
-
監(jiān)聽器接口
一轿腺、監(jiān)聽對象創(chuàng)建/銷毀的監(jiān)聽器接口- 監(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
- 監(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失效時間
- 監(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對象就會銷毀
- 代碼 :
- 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ā)步驟:
- 寫一個普通java類,實(shí)現(xiàn)相關(guān)接口瘾晃;
- 配置(web.xml)
- 監(jiān)聽器開發(fā)步驟:
- 聲明周期監(jiān)聽器: 監(jiān)聽對象的創(chuàng)建鹅经、銷毀的過程寂呛!
<!-- 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ān)聽:request/session/servletContext對象屬性的變化强胰!
總結(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í)行
- Filter接口中有一個doFilter方法孙乖,當(dāng)開發(fā)人員編寫好Filter,并配置對哪個web資源進(jìn)行攔截后蜗帜,WEB服務(wù)器每次在調(diào)用web資源的service方法之前蔬顾,都會先調(diào)用一下filter的doFilter方法湘捎,因此消痛,在該方法內(nèi)編寫代碼可達(dá)到如下目的:
為什么需用到過濾器 : 項(xiàng)目開發(fā)中,經(jīng)常會涉及到重復(fù)代碼的實(shí)現(xiàn)仪搔!
-
過濾器烤咧,設(shè)計執(zhí)行流程:(OOAD : 面向?qū)ο蟮姆治雠c設(shè)計 - 時序圖)
- 用戶訪問服務(wù)器
- 過濾器: 對Servlet請求進(jìn)行攔截
- 先進(jìn)入過濾器煮嫌, 過濾器處理
- 過濾器處理完后, 在放行抱虐, 此時昌阿,請求到達(dá)Servlet/JSP
- Servlet處理
- Servlet處理完后,再回到過濾器, 最后在由tomcat服務(wù)器相應(yīng)用戶恳邀;
-
開發(fā)步驟 :
- 寫一個普通java類懦冰,實(shí)現(xiàn)Filter接口
- 配置過濾器
-
過濾器相關(guān)Api
-
interface Filter
: 過濾器核心接口-
Void init(filterConfig);
: 初始化方法,在服務(wù)器啟動時候執(zhí)行 -
Void doFilter(request,response,filterChain);
: 過濾器攔截的業(yè)務(wù)處理方法 -
Void destroy();
: 銷毀過濾器實(shí)例時候調(diào)用
-
-
interface FilterConfig
: 獲取初始化參數(shù)信息 -
interface FilterChain
: 過濾器鏈參數(shù)谣沸;一個個過濾器形成一個執(zhí)行鏈儿奶;-
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>
- 默認(rèn)攔截的類型:(直接訪問或者重定向
- 共性問題:
- 過濾器 : 方法參數(shù)沒有自動命名粥惧,說明沒有關(guān)聯(lián)源碼-> 關(guān)聯(lián)tomcat或servlet源代碼
- 連接池 : 多刷新幾次咏删,報錯!
- 連接沒關(guān) :
QueryRunner qr = new QueryRunner();
qr.update(con,sql);// 這里con一定要關(guān)閉 - 注意:dataSource 確定一個項(xiàng)目創(chuàng)建一次 :
QueryRunner qr = new QueryRunner(dataSource);
3.修改連接池參數(shù)配置
- 連接沒關(guān) :
- 編碼
- request.setCharacterEncoding("UTF-8"); // 設(shè)置POST提交的請求的編碼
- response.setCharacterEncoding("UTF-8"); // 設(shè)置相應(yīng)體的編碼
- response.setContentType("text/html;charset=UTF-8"); // 設(shè)置頁面打開時候時候的編碼格式、 設(shè)置相應(yīng)體的編碼
- 開發(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)步驟:
- 建庫、建表恍风、建項(xiàng)目蹦狂、引入jar文件
- entity
- Admin.java
- Employee.java
- Dao
- AdminDao
- EmployeeDao
- Servcie
- Servlet
-
注意 : 網(wǎng)站訪問