1. 程式人生 > >Listener & Filter

Listener & Filter

Listener

監聽器:監聽某一個事件的發生,狀態的改變

監聽器的內部機制:其實就是介面回撥

介面回撥:

需求:

A在執行迴圈,當迴圈到5的時候,通知B。

事先先把一個物件傳遞給A,當A執行到5的時候,通過這個物件,來呼叫B中的方法。但是注意,不是直接傳遞B的例項,而是傳遞一個介面的例項過去。

 A和B兩者中間藉助介面去聯絡上。

所以一開始在執行A的print方法時,先把一個介面的實現類傳遞給A,後面A在根據這個物件,在呼叫B的方法。

Web監聽器:

總共有8個 劃分為三種類型

1.定義一個類,實現介面

2.註冊| 配置監聽器

 

 

1.監聽三個作用域建立和銷燬

   request   ---httpServletRequest

   session   ---httpSession

   application --- ServletContext

       1.ServletContextListener 

              servletcontext建立:

                      1.啟動伺服器的時候

              servletContext銷燬:

                      2.關閉伺服器,從伺服器移除專案

       2.ServletRequestListener

                 request建立:

                             訪問伺服器上的任意資源都會有請求出現

                             訪問html、jsp、servlet

                  request銷燬:

                              伺服器已經對這次請求作出了響應

       3.HttpSessionListener

                    session的建立

                              只要呼叫getSession

                               html:不會

                               jsp:會   getSession();

                               servlet : 會

                   session的銷燬

                               超時  30分鐘

                               非正常關閉    銷燬

                                正常關閉伺服器(序列化)

      作用:

                   ServletContextListener

                            利用它來,在servletcontext建立的時候,

                             1.完成自己想要的初始化工作

                              2.執行自定義任務排程。執行某一個任務。Timer

                    HttpSessionListener

                                統計線上人數。

2.監聽三個作用域屬性狀態變更

request  ---  ServletRequestAttributeListener

session  ---  HttpSessionAttributeListener

servletContext  ---  ServletContextAttributeListener 

>可以監聽在作用域中值 新增 | 替換 | 移除的動作。

 

3.監聽httpSession裡面存值的狀態變更

這一類監聽器不用註冊。

HttpSessionBindingListener

>監聽物件與session 繫結和解除繫結 的動作

1.讓javaBean實現該介面即可

 

HttpSessionActivationListener

>用於監聽現在session的值  是 鈍化(序列化)還是活化(反序列化)的動作

鈍化(序列化):把記憶體中的資料 儲存到硬碟上

活化(反序列化):把硬碟中的資料讀取到記憶體中

 session的鈍化活化的用意:

session中的值可能會很多,並且我們有很長一段時間不使用這個 記憶體中的值,那麼可以考慮把session的值可以儲存到硬碟上【鈍化】,等下一次在使用的時候,在從硬碟上提取出來。【活化】

如何讓session在一定時間內鈍化:

做配置即可:

在自己的web工程專案中的META-INF/context.xml,只對當前的工程生效。

maxIdleSwap:1分鐘不用就鈍化

directory:鈍化後的那個檔案存放的目錄位置

<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
	<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>

Filter:

過濾器,其實就是對客戶端發出來的請求進行過濾,瀏覽器發出,然後伺服器派servlet處理。在中間就可以過濾,其實過濾器起到的是攔截的作用。

作用:1.對一些敏感詞彙進行過濾

            2.統一設定編碼

            3.自動登入

 如何使用Filter:

1.定義一個類,實現Filter

2.註冊過濾器

在web.xml裡面註冊,註冊的手法與servlet基本一樣

Filter的生命週期:

建立:在伺服器啟動的時候就建立

銷燬:伺服器停止的時候

Filter執行順序:

1.客戶端發出請求,先經過過濾器,如果過濾器放行,那麼才能到servlet

2.如果有多個過濾器,那麼他們會按照註冊的對映順序來排隊。只要有一個過濾器,不放行,那麼後面排隊的過濾器以及咱們的servlet都不會收到請求。

細節:

1.init方法的引數 FilterConfig

2.在doFilter方法裡面操作,使用引數chain  chain.doFilter(request,response);放行,讓請求到達下一個目標

3.<url-pattern>/*</url-pattern>

1.全路徑匹配  以/開始     /LoginServlet

2.以目錄匹配  以/開始  以*結束  /demo01/*

3.以後綴名匹配  以*開始  以後綴名結束     *.jsp   *.html   *.do

4.針對dispatcher設定

 

自動登入:

BeanUtilsDemo:

try {
			Map map = request.getParameterMap();
			UserBean bean = new UserBean();
			BeanUtils.populate(bean, map);
			System.out.println("2222bean="+bean.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

try {
			//註冊自己的日期轉換器
			ConvertUtils.register(new MyDateConverter(), Date.class);
			Map map = request.getParameterMap();
			UserBean bean = new UserBean();
            //轉化map中的資料,放置到bean物件上
			BeanUtils.populate(bean, map);
			System.out.println("2222bean="+bean.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

過濾器程式碼:

1.先判斷session是否有效,如果有效,就不用取cookie了,直接放行

2.如果session失效了,那麼就取cookie

          1.沒有cookie 放行

          2.有cookie

                         1.取出來cookie的值,然後完成登入

                         2.把這個使用者的值儲存到session中

                         3.放行

public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		//先判斷,現在session中還有沒有那個userBean
		UserBean userBean = (UserBean) request.getSession().getAttribute("userBean");
		//還有,有效
		if(userBean != null) {
			chain.doFilter(request, response);
		}
		else
		{
			//代表session失效了
			//2.看cookie
			//1/來請求的時候,先從請求裡面取出cookie,但是cookie有很多的key-value
			Cookie[] cookies = request.getCookies();
			//2.從一堆的cookie裡面找出我們以前給瀏覽器發的那個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();
				try {
					userBean = dao.login(user);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					chain.doFilter(request, response);
				}
				//使用session存這個值到域中,方便下一次未過期前還可以用
				request.getSession().setAttribute("userBean", userBean);
				chain.doFilter(request, response);
			}
		}
		
		
	}

servlet:

public class LoginServlet extends HttpServlet {
	
	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");
			//System.out.println(username + "=" + password+"="+autoLogin); 
			UserBean user = new UserBean();
			user.setUsername(username);
			user.setPassword(password);
			UserDao dao = new UserDaoImpl();
			UserBean userBean = dao.login(user);
			System.out.println("有");
			if(userBean != null) {
				//頁面提交上來的時候,是否選擇了自動登入
				
				if("on".equals(autoLogin))
				{
					//傳送cookie給客戶端
					Cookie cookie = new Cookie("auto_login", username+"#itheima#"+password);
					cookie.setMaxAge(60*60*24*7);
					cookie.setPath(request.getContextPath());
					
					response.addCookie(cookie);
				}
				//成功了,進入首頁
				request.getSession().setAttribute("userBean", userBean);
				response.sendRedirect("index.jsp");
			}
			else
			{
				//不成功
				request.getRequestDispatcher("login.jsp").forward(request, response);
				
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}