1、Listener監聽器java
Javaweb開發中的監聽器,是用於監聽web常見對象 HttpServletRequest HttpSession ServletContext 監聽它們的建立與銷燬 屬性變化 session綁定javaBean
一、監聽機制mysql
事件 就是一個事情 事件源 產生這個事情的源頭 監聽器 用於監聽指定的事件的對象 註冊監聽 要想讓監聽器能夠監聽到事件產生,必須對其進行註冊。 ------------------------------
二、Javaweb開發中常見監聽器
2.一、監聽域對象的建立與銷燬
監聽ServletContext建立與銷燬 ServletContextListener
監聽HttpSession建立與銷燬 HttpSessionListener
監聽HttpServletRequest建立與銷燬 ServletRequestListener
2.二、監聽域對象的屬性變化
監聽ServletContext屬性變化 ServletContextAttributeListener
監聽HttpSession屬性變化 HttpSessionAttributeListener
監聽HttpServletRequest屬性變化 ServletRequestAttributeListenerweb
2.三、監聽session綁定javaBean
它是用於監聽javaBean對象是否綁定到了session域 HttpSessionBindingListener
它是用於監聽javaBean對象的活化與鈍化 HttpSessionActivationListener
三、監聽器的快速入門算法
關於建立一個監聽器的步驟
1.建立一個類,實現指定的監聽器接口
2.重寫接口中的方法
3.在web.xml文件中對監聽器進行註冊。
3.一、關於域對象建立與銷燬的演示
1.ServletContext對象的建立與銷燬
這個對象是在服務器啓動時建立的,在服務器關閉時銷燬的。sql
2.HttpSession對象的建立與銷燬
HttpSession session=request.getSession();
Session銷燬
1.默認超時 30分鐘
2.關閉服務器
3.invalidate()方法
4.setMaxInactiveInterval(int interval) 能夠設置超時時間apache
問題:直接訪問一個jsp頁面時,是否會建立session?
會建立,由於咱們默認狀況下是能夠在jsp頁面中直接使用session內置對象的。設計模式
3.HttpServletRequest建立與銷燬
Request對象是發送請求服務器就會建立它,當響應產生時,request對象就會銷燬。數組
3.二、演示了Request域對象中屬性變化瀏覽器
在java的監聽機制中,它的監聽器中的方法都是有參數的,參數就是事件對象,而咱們能夠經過事件對象直接獲取事件源。
3.三、演示session綁定javaBean
1.javaBean對象自動感知被綁定到session中.
HttpSessionBindingListener 這個接口是由javaBean實現的,而且不須要在web.xml文件中註冊.服務器
2.javabean對象能夠活化或鈍化到session中。
HttpSessionActivationListener若是javaBean實現了這個接口,那麼當咱們正常關閉服務器時,session中的javaBean對象就會被鈍化到咱們指定的文件中。
當下一次在啓動服務器,由於咱們已經將對象寫入到文件中,這時就會自動將javaBean對象活化到session中。
咱們還須要個context.xml文件來配置鈍化時存儲的文件
在meta-inf目錄下建立一個context.xml文件
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager> </Context>
案例-定時銷燬session
1.怎樣能夠將每個建立的session全都保存起來?
咱們能夠作一個HttpSessionListener,當session對象建立時,就將這個session對象裝入到一個集合中.
將集合List<HttpSession>保存到ServletContext域中。
2.怎樣能夠判斷session過時了?
在HttpSession中有一個方法public long getLastAccessedTime()
它能夠獲得session對象最後使用的時間。
可使用invalidate方法銷燬。
咱們上面的操做須要使用任務調度功能. 在java中有一個Timer定時器類
關於三個域對象獲取
若是在Servlet中要獲取 request,在方法上就有,request.getSession() getServletContext();
若是咱們有request對象了, request.getSession() request.getSession().getServletCotnext();
程序在使用時,須要考慮併發問題,由於咱們在web中,它必定是一個多線程的,那麼咱們的程序對集合進行了添加,還有移除操做。
2、Filter過濾器(重要)
Javaweb中的過濾器能夠攔截全部訪問web資源的請求或響應操做。
一、Filter快速入門
1.一、步驟:
1.建立一個類實現Filter接口
2.重寫接口中方法 doFilter方法是真正過濾的。
3.在web.xml文件中配置
注意:在Filter的doFilter方法內若是沒有執行chain.doFilter(request,response)
那麼資源是不會被訪問到的。
1.二、FilterChain
FilterChain 是 servlet 容器爲開發人員提供的對象,它提供了對某一資源的已過濾請求調用鏈的視圖。過濾器使用 FilterChain 調用鏈中的下一個過濾器,若是調用的過濾器是鏈中的最後一個過濾器,則調用鏈末尾的資源。
問題:怎樣能夠造成一個Filter鏈?
只要多個Filter對同一個資源進行攔截就能夠造成Filter鏈
問題:怎樣肯定Filter的執行順序?
由<filter-mapping>來肯定 1.三、Filter生命週期
Servlet生命週期:
實例化 --》 初始化 --》 服務 --》 銷燬
當服務器啓動,會建立Filter對象,並調用init方法,只調用一次.
當訪問資源時,路徑與Filter的攔截路徑匹配,會執行Filter中的doFilter方法,這個方法是真正攔截操做的方法.
當服務器關閉時,會調用Filter的destroy方法來進行銷燬操做.
1.四、FilterConfig 在Filter的init方法上有一個參數,類型就是FilterConfig. FilterConfig它是Filter的配置對象,它能夠完成下列功能
1.獲取Filtr名稱
2.獲取Filter初始化參數
3.獲取ServletContext對象。
問題:怎樣在Filter中獲取一個FIlterConfig對象?
1.五、Filter配置
基本配置 <filter> <filter-name>filter名稱</filter-name> <filter-class>Filter類的包名.類名</filter-class> </filter> <filter-mapping> <filter-name>filter名稱</filter-name> <url-pattern>路徑</url-pattern> </filter-mapping> 關於其它配置 1.<url-pattern> 徹底匹配 以」/demo1」開始,不包含通配符* 目錄匹配 以」/」開始 以*結束 擴展名匹配 *.xxx 不能寫成/*.xxx 2.<servlet-name> 它是對指定的servlet名稱的servlet進行攔截的。 3.<dispatcher> 能夠取的值有 REQUEST FORWARD ERROR INCLUDE
它的做用是:當以什麼方式去訪問web資源時,進行攔截操做.
1.REQUEST 當是從瀏覽器直接訪問資源,或是重定向到某個資源時進行攔截方式配置的 它也是默認值
2.FORWARD 它描述的是請求轉發的攔截方式配置
3.ERROR 若是目標資源是經過聲明式異常處理機制調用時,那麼該過濾器將被調用。除此以外,過濾器不會被調用。
4.INCLUDE 若是目標資源是經過RequestDispatcher的include()方法訪問時,那麼該過濾器將被調用。除此以外,該過濾器不會被調用
3、自動登錄
一、建立庫與表 CREATE DATABASE day17
USE day17
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100), PASSWORD VARCHAR(100)
)
INSERT INTO USER VALUES(NULL,"tom","123");
二、自動登錄功能實現:
1.當用戶登錄成功後,判斷是否勾選了自動登錄,若是勾選了,就將用戶名與密碼持久化存儲到cookie中
2.作一個Filter,對須要自動登錄的資源進行攔截
問題
1.若是用戶想要登錄操做,還須要自動登錄嗎?
2.若是用戶已經登錄了,還須要自動登錄嗎?
4、MD5加密
在mysql中能夠對數據進行md5加密 Md5(字段) UPDATE USER SET PASSWORD=MD5(PASSWORD); 在java中也提供了md5加密 /**
*/
public static String md5(String plainText) {
byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest( plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("沒有md5這個算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16); for (int i = 0; i < 32 - md5code.length(); i++) { md5code = "0" + md5code; } return md5code;
5、全局的編碼過濾器
分析: 咱們以前作的操做,只能對post請求是ok
怎樣能夠作成一個通用的,能夠處理post,get全部的請求的?
在java中怎樣能夠對一個方法進行功能加強?
1.繼承
2.裝飾設計模式
1.建立一個類讓它與被裝飾類實現同一個接口或繼承同一個父類
2.在裝飾類中持有一個被裝飾類的引用
3.重寫要加強的方法
問題:咱們獲取請求參數有如下方法
1.getParameter
2.getPrameterValues
3.getParameterMap
這三個方法均可以獲取請求參數。
分析後,咱們知道getParameter與getParameterValue方法能夠依賴於getParamterMap方法來實現。
// 這個就是咱們對request進行裝飾的類
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;// 是用於接收外部傳遞的原始的request
public MyRequest(HttpServletRequest request) {
super(request); // 是由於父類沒有無參數構造 this.request = request;
}
// @Override
// public String getParameter(String name) {
// // 1.獲得原來的getParameter方法的值
// String value = request.getParameter(name); // 亂碼
//
// try {
// return new String(value.getBytes("iso8859-1"), "utf-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// return null;
// }
@Override
public String getParameter(String name) {
if (name != null) { String[] st = (String[]) getParameterMap().get(name); if (st != null && st.length > 0) { return st[0]; } } return null;
}
@Override
public String[] getParameterValues(String name) {
if (name != null) { return (String[]) getParameterMap().get(name); } return null;
}
private boolean flag = true;
@Override
public Map getParameterMap() {
// 1.獲得原始的map集合 Map<String, String[]> map = request.getParameterMap();// 亂碼 if (flag) { // 2.將map集合中的String[]獲得,解決每個元素的亂碼問題. for (String key : map.keySet()) { String[] st = map.get(key); // 獲得每個數組 for (int i = 0; i < st.length; i++) { try { st[i] = new String(st[i].getBytes("iso8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag = false; } return map;
}
}