Listener
監(jiān)聽器
- 能做什么事碧查?
監(jiān)聽某一個(gè)事件的發(fā)生运敢。 狀態(tài)的改變。
- 監(jiān)聽器的內(nèi)部機(jī)制
其實(shí)就是接口回調(diào).
接口回調(diào)
- 需求:
A在執(zhí)行循環(huán)忠售,當(dāng)循環(huán)到5的時(shí)候传惠, 通知B。
事先先把一個(gè)對象傳遞給 A 稻扬, 當(dāng)A 執(zhí)行到5的時(shí)候卦方,通過這個(gè)對象,來調(diào)用B中的方法泰佳。 但是注意盼砍,不是直接傳遞B的實(shí)例,而是傳遞一個(gè)接口的實(shí)例過去乐纸。
Web監(jiān)聽器
總共有8個(gè) 劃分成三種類型
定義一個(gè)類衬廷,實(shí)現(xiàn)接口
注冊 | 配置監(jiān)聽器
監(jiān)聽三個(gè)作用域創(chuàng)建和銷毀
request ---httpServletRequest
session ---httpSession
aapplication --- ServletContext
1. ServletContextListener
servletcontext創(chuàng)建:
1. 啟動(dòng)服務(wù)器的時(shí)候
servletContext銷毀:
2. 關(guān)閉服務(wù)器. 從服務(wù)器移除項(xiàng)目
2. ServletRequestListener
request創(chuàng)建:
訪問服務(wù)器上的任意資源都會(huì)有請求出現(xiàn)。
訪問 html: 會(huì)
訪問 jsp: 會(huì)
訪問 servlet : 會(huì)
request銷毀:
服務(wù)器已經(jīng)對這次請求作出了響應(yīng)汽绢。
public class MyRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("servletrequest 銷毀了");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("servletrequest 初始化了");
}
}
<listener>
<listener-class>com.itheima.listener.MyRequestListener</listener-class>
</listener>
3. HttpSessionListener
session的創(chuàng)建
只要調(diào)用getSession
html: 不會(huì)
jsp: 會(huì) getSession();
servlet: 會(huì)
session的銷毀
超時(shí) 30分鐘
非正常關(guān)閉 銷毀
正常關(guān)閉服務(wù)器(序列化)
public class MySessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("創(chuàng)建session了");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("銷毀session了");
}
}
作用:
ServletContextListener
利用它來吗跋,在servletcontext創(chuàng)建的時(shí)候,
1. 完成自己想要的初始化工作
2. 執(zhí)行自定義任務(wù)調(diào)度宁昭。 執(zhí)行某一個(gè)任務(wù)跌宛。 Timer
HttpSessionListener
統(tǒng)計(jì)在線人數(shù).
監(jiān)聽三個(gè)作用域?qū)傩誀顟B(tài)變更
可以監(jiān)聽在作用域中值 添加 | 替換 | 移除的動(dòng)作。
-
servletContext --- ServletContextAttributeListener
-
request --- ServletRequestAttributeListener
-
session --- HttpSessionAttributeListener
監(jiān)聽httpSession里面存值的狀態(tài)變更
這一類監(jiān)聽器不用注冊积仗。
- HttpSessionBindingListener
監(jiān)聽對象與session 綁定和解除綁定 的動(dòng)作
1. 讓javaBean 實(shí)現(xiàn)該接口即可
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("對象被綁定進(jìn)來了");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("對象被解除綁定");
}
- HttpSessionActivationListener
用于監(jiān)聽現(xiàn)在session的值 是 鈍化 (序列化)還是活化 (反序列化)的動(dòng)作
- 鈍化 (序列化)
把內(nèi)存中的數(shù)據(jù) 存儲(chǔ)到硬盤上
- 活化 (反序列化)
把硬盤中的數(shù)據(jù)讀取到內(nèi)存中委乌。
- session的鈍化活化的用意何在
session中的值可能會(huì)很多柿扣, 并且我們有很長一段時(shí)間不使用這個(gè)內(nèi)存中的值, 那么可以考慮把session的值可以存儲(chǔ)到硬盤上【鈍化】,等下一次在使用的時(shí)候踏堡,在從硬盤上提取出來。 【活化】
- 如何讓session的在一定時(shí)間內(nèi)鈍化.
做配置即可
1. 在tomcat里面 conf/context.xml 里面配置
對所有的運(yùn)行在這個(gè)服務(wù)器的項(xiàng)目生效
2. 在conf/Catalina/localhost/context.xml 配置
對 localhost生效锦担。 localhost:8080
3. 在自己的web工程項(xiàng)目中的 META-INF/context.xml
只對當(dāng)前的工程生效镀岛。
maxIdleSwap : 1分鐘不用就鈍化
directory : 鈍化后的那個(gè)文件存放的目錄位置。
D:\tomcat\apache-tomcat-7.0.52\work\Catalina\localhost\ListenerDemo\itheima
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context>
Filter
過濾器 渺氧, 其實(shí)就是對客戶端發(fā)出來的請求進(jìn)行過濾旨涝。 瀏覽器發(fā)出, 然后服務(wù)器派servlet處理侣背。 在中間就可以過濾白华, 其實(shí)過濾器起到的是攔截的作用慨默。
-
作用
- 對一些敏感詞匯進(jìn)行過濾
- 統(tǒng)一設(shè)置編碼
- 自動(dòng)登錄
...
如何使用Filter
-
定義一個(gè)類, 實(shí)現(xiàn)Filter
public class FilterDemo implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("來到過慮器了弧腥。厦取。。"); chain.doFilter(request, response); } public void init(FilterConfig fConfig) throws ServletException { } }
注冊過濾器
在web.xml里面注冊鸟赫,注冊的手法與servlet基本一樣蒜胖。
<filter>
<display-name>FilterDemo</display-name>
<filter-name>FilterDemo</filter-name>
<filter-class>com.itheima.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter的生命周期
- 創(chuàng)建
在服務(wù)器啟動(dòng)的時(shí)候就創(chuàng)建。
- 銷毀
服務(wù)器停止的時(shí)候抛蚤。
Filter執(zhí)行順序
客戶端發(fā)出請求台谢,先經(jīng)過過濾器, 如果過濾器放行岁经,那么才能到servlet
如果有多個(gè)過濾器朋沮, 那么他們會(huì)按照注冊的映射順序 來 排隊(duì)。 只要有一個(gè)過濾器缀壤, 不放行樊拓,那么后面排隊(duì)的過濾器以及咱們的servlet都不會(huì)收到請求。
Filter細(xì)節(jié):
init方法的參數(shù) FilterConfig , 可以用于獲取filter在注冊的名字 以及初始化參數(shù)塘慕。 其實(shí)這里的設(shè)計(jì)的初衷與ServletConfig是一樣的筋夏。
如果想放行,那么在doFilter 方法里面操作图呢,使用參數(shù) chain
chain.doFilter(request, response); 放行条篷, 讓請求到達(dá)下一個(gè)目標(biāo)。
-
<url-pattern>/*</url-pattern> 寫法格式與servlet一樣蛤织。
-
全路徑匹配 以 / 開始
/LoginServlet
-
以目錄匹配 以 / 開始 以 * 結(jié)束
/demo01/*
-
以后綴名匹配 以 * 開始 以后綴名結(jié)束
*.jsp *.html *.do
-
-
針對 dispatcher 設(shè)置
REQUEST : 只要是請求過來赴叹,都攔截,默認(rèn)就是REQUEST FORWARD : 只要是轉(zhuǎn)發(fā)都攔截指蚜。 ERROR : 頁面出錯(cuò)發(fā)生跳轉(zhuǎn) INCLUDE : 包含頁面的時(shí)候就攔截乞巧。
自動(dòng)登錄
- 需求分析
1. 搭建環(huán)境
搭建數(shù)據(jù)庫
搭建頁面
登錄servlet代碼
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String userName = request.getParameter("username");
String password = request.getParameter("password");
String autoLogin = request.getParameter("auto_login");
UserBean user = new UserBean();
user.setUsername(userName);
user.setPassword(password);
UserDao dao = new UserDaoImpl();
UserBean userBean = dao.login(user);
if(userBean != null){
//成功了,進(jìn)入首頁
request.getSession().setAttribute("userBean", userBean);
response.sendRedirect("index.jsp");
}else{
//不成功...
request.getRequestDispatcher("login.jsp").forward(request, response);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
過濾器代碼
過濾器的核心不是完成攔截不給 摊鸡, 還是放行顯示绽媒。 它的核心是在放行之前,幫用戶完成登錄的功能免猾。
- 實(shí)現(xiàn)思路
先判斷session是否有效些椒, 如果有效,就不用取cookie了掸刊,直接放行。
-
如果session失效了赢乓,那么就取 cookie忧侧。
沒有cookie 放行
-
有cookie
1. 取出來cookie的值石窑,然后完成登錄 2. 把這個(gè)用戶的值存儲(chǔ)到session中 3. 放行。 /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { HttpServletRequest request = (HttpServletRequest) req; //先判斷蚓炬,現(xiàn)在session中還有沒有那個(gè)userBean. UserBean userBean = (UserBean) request.getSession().getAttribute("userBean"); //還有松逊,有效。 if(userBean != null){ chain.doFilter(request, response); }else{ //代表session失效了肯夏。 //2. 看cookie经宏。 //1. 來請求的時(shí)候,先從請求里面取出cookie , 但是cookie有很多的key-value Cookie[] cookies = request.getCookies(); //2. 從一堆的cookie里面找出我們以前給瀏覽器發(fā)的那個(gè)cookie Cookie cookie = CookieUtil.findCookie(cookies, "auto_login"); //第一次來 if(cookie == null){ chain.doFilter(request, response); }else{ //不是第一次驯击。 String value = cookie.getValue(); String username = value.split("#itheima#")[0]; String password = value.split("#itheima#")[1]; //完成登錄 UserBean user = new UserBean(); user.setUsername(username); user.setPassword(password); UserDao dao = new UserDaoImpl(); userBean = dao.login(user); //使用session存這個(gè)值到域中烁兰,方便下一次未過期前還可以用。 request.getSession().setAttribute("userBean", userBean); chain.doFilter(request, response); } } } catch (Exception e) { e.printStackTrace(); chain.doFilter(req, response); } }
BeanUtils的使用
BeanUtils.populate(bean, map);
//注冊自己的日期轉(zhuǎn)換器
ConvertUtils.register(new MyDateConverter(), Date.class);
//轉(zhuǎn)化數(shù)據(jù)
Map map = request.getParameterMap();
UserBean bean = new UserBean();
轉(zhuǎn)化map中的數(shù)據(jù)徊都,放置到bean對象身上
BeanUtils.populate(bean, map);
總結(jié)
Listener
8個(gè)
三種類型
針對三個(gè)作用域的創(chuàng)建和銷毀
針對三個(gè)作用域的值改變 【添加 | 替換 | 移除】
針對session中的值 【鈍化 活化】 沪斟, 【綁定 解綁】
鈍化 ( 序列化 )
內(nèi)存中的對象存儲(chǔ)到硬盤
超時(shí)失效。 session銷毀了暇矫。
非正常關(guān)閉服務(wù)器主之, 鈍化 。 正常關(guān)閉服務(wù)器 銷毀
設(shè)置了session李根,多久時(shí)間槽奕。 context.xml
活化 (反序列化)
從硬盤里面讀取到內(nèi)存
ServletContextListner : 應(yīng)用被部署的時(shí)候, 服務(wù)器加載這個(gè)項(xiàng)目的時(shí)候房轿,做一些初始化工作粤攒, 任務(wù)調(diào)度。
HttpSessionListener : 統(tǒng)計(jì)在線人數(shù)
HttpSessionActivationListener : 鈍化活化處理
Filter
使用頻率更高
- 如果要寫一個(gè)過濾器冀续。
- 定義一個(gè)類琼讽,實(shí)現(xiàn)接口 Filter
- 注冊 . web.xml . 與servlet相似洪唐。
- 過濾器放行钻蹬。
chain.doFilter(request, response);
-
過濾器生命周期
創(chuàng)建: 服務(wù)器加載這個(gè)項(xiàng)目的時(shí)候創(chuàng)建實(shí)例
銷毀: 關(guān)閉服務(wù)器或者從服務(wù)器中移除項(xiàng)目的時(shí)候。