JavaWeb---Listener和Filter理解接口調用(附帶自動登錄小案例)

JavaWeb三大核心主鍵之------Listener

Listener即監聽器的意思,它和ServletFilter並稱JavaWeb三大核心組件。它的作用就是監聽某一個事件的發生或者狀態的改變並對此作出反應,它是Servlet規範的另一個高級特性,我們主要通過使用它來監聽Java Web程序中的事件,比如創建、修改、刪除Session、request、context等,並觸發響應的事件。利用Listener能夠用很少的代碼實現很絢麗的效果,在開發中常用來監聽某個servlet被加載,然後做一些初始化得工作。

它的內部機制就是接口回調,這裏就引入一個新的概念,何爲接口回調?

理解接口回調

簡單來說接口回調就是可以把使用某一接口的類創建的對象的引用賦給該接口聲明的接口變量,那麼該接口變量就可以調用被類實現的接口的方法。它充分的體現了java多態的特性,下面是關於接口回調的例子圖。

在這裏插入圖片描述

Listener總共有8個,根據其監聽的對象或功能又可以分爲三種類型:

  • 監聽三個作用域創建和銷燬
    • ServletContextListener
    • ServletRequestListener
    • HttpSessionListener
  • 監聽三個作用域屬性狀態變更
    • ServletContextAttributeListener
    • ServletRequestAttributeListener
    • HttpSessionAttributeListener
  • 監聽httpSession裏面存值的狀態變更
    • HttpSessionBindingListener
    • HttpSessionActivationListener

監聽三個作用域創建和銷燬

這三個作用域就是request 、session、aapplication

  1. ServletContextListener—監聽servletContext的創建和銷燬

    servletcontext創建: 啓動服務器的時候
    servletContext銷燬:關閉服務器. 從服務器移除項目

  2. ServletRequestListener–監聽servletRequest的創建和銷燬

    request創建:訪問服務器上的任意資源都會有request的創建。
    request銷燬:服務器已經對這次請求作出了響應。

    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需要在web.xml中註冊要使用的Listener,格式如下

      <listener>
    	  	<listener-class>com.itheima.listener.MyRequestListener</listener-class>
      </listener>
    
  3. HttpSessionListener----監聽session的創建和銷燬

    session的創建:只要調用getSession
    訪問jsp和servlet時候就會創建session

    session的銷燬:session作用超時、非正常關閉

     代碼示例
    
     public class MySessionListener implements HttpSessionListener {
    
     		@Override
     		public void sessionCreated(HttpSessionEvent se) {
     			System.out.println("創建session了");
     		}
     	
     		@Override
     		public void sessionDestroyed(HttpSessionEvent se) {
     			System.out.println("銷燬session了");
     		}
     	}
    

    可以通過使用它來統計在線人數.

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

它可以監聽在作用域中值 添加 | 替換 | 移除的動作。

  • servletContext — ServletContextAttributeListener
    在這裏插入圖片描述

  • request — ServletRequestAttributeListener

    在這裏插入圖片描述

  • session — HttpSessionAttributeListener

    在這裏插入圖片描述
    ------------------以上圖片均從我學習的視頻教程裏面獲得-----------------

監聽httpSession裏面存值的狀態變更

這種監聽器不用註冊

  • HttpSessionBindingListener—用於監聽對象與session 綁定和解除綁定 的動作

    直接讓實體類對象實現該接口即可

      	@Override
      	public void valueBound(HttpSessionBindingEvent event) {
      		System.out.println("對象被綁定");
      	}
      
      	@Override
      	public void valueUnbound(HttpSessionBindingEvent event) {
      		System.out.println("對象被解除綁定");
      	}
    
  • HttpSessionActivationListener–用於監聽現在session的值是序列化還是反序列的動作

    序列化又稱爲鈍化,是指把內存中的數據 存儲到硬盤上
    反序列化又稱爲活化,是指把硬盤中的數據讀取到內存中

    這類監聽器的主要意義就是減輕內存的負擔,將不經常使用的值存入到硬盤中,要使用的時候再加載進內存。

由於這類監聽器不需要註冊,但是要在服務器裏面做配置,在自己的web工程項目中的 META-INF/context.xml中配置,使這個監聽器只對當前的工程生效。

<Context>
		<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
			<Store className="org.apache.catalina.session.FileStore" directory="gzgs"/>
		</Manager>
</Context>
maxIdleSwap : 1分鐘不用就序列化
directory : 序列化後的那個文件存放的目錄位置。



JavaWeb三大核心主鍵之------Filter

Filter即過濾器,同樣的它也是JavaWeb三大核心組件之一,而且和Listener相比,在開發中它被使用得更多,很常見的一個例子就是在我們日常打遊戲的時候,比如隊友有神操作我們看不下去忍不住想“誇”他兩句的時候,你會發現你想誇他的話莫名奇妙就變成了 你**,這就是Filter的作用,這還不止,我們還可以利用它來實現網站自動登錄的效果等。

那麼怎麼使用Filter?

  1. 定義一個類, 實現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 {
     	}
     
     }
    
  2. 註冊過濾器
    在項目的web.xml裏面註冊,註冊的手法與servlet相類似。

       	<filter>
         <display-name>FilterDemo</display-name>
         <filter-name>FilterDemo</filter-name>
         <filter-class>com.gzgs.filter.FilterDemo</filter-class>
       </filter>
       <filter-mapping>
         <filter-name>FilterDemo</filter-name>
         <url-pattern>/*</url-pattern>
       </filter-mapping>
    

    這樣一來你向服務器提交請求,想訪問filter項目底下的任何資源之前都會經過一下過濾器, 可以通過標籤< url-pattern >/*</ url-pattern >來設置我們想要攔截的地址路徑,/ *表示攔截該項目底下所有請求。

Filter的生命週期

  • 創建:服務器加載Filter所在的項目的時候,服務器會自動調用init()方法,這樣一來Filter就被自動創建了。
  • 銷燬:服務器關閉的時候或者把項目從服務器中移除,又或者Filter中的destroy()被調用的時候就被銷燬了。

Filter執行順序

  • 客戶端發出請求—>先經過過濾器, 如果過濾器放行—>servlet
  • 如果一個項目有多個過濾器, 那麼就按照註冊的映射順序來排隊。 如果其中有一個過濾器不放行,那麼後面排隊的過濾器以及咱們的servlet都不會收到請求。

在這裏插入圖片描述

Filter放行------chain.doFilter();

dispatcher 設置

  • REQUEST : 只要是請求過來,都攔截,默認就是REQUEST
  • FORWARD : 只要是轉發都攔截。
  • ERROR : 頁面出錯發生跳轉
  • INCLUDE : 包含頁面的時候就攔截。

自動登錄小案例

1.準備數據庫
2.搭建頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
	$(function(){
		$("#submit").click(function(){
			//獲取值
			var username=$("#username").val();
			var password=$("#password").val();
			var auto_login=$("#auto_login").val();
			
			$.post("AutoLoginServlet",{username:username,password:password,auto_login:auto_login},function(data,status){
				var s=data;
				if("Login Success"==s){
					
					window.location.href = "index.jsp";
				}else{
					$("#span").html("<font size='1' color='red'>"+data+"</font>")
				}
			})
		})
	})
</script>
</head>
<body>
	<table border=1 style="width: 400px; height:400px" align="center">
		<tr align="center">
			<td colspan="2"><b>請登錄</b></td>
			
		</tr>
		<tr align="center">
			<td>用戶名</td>
			<td>
				<input type="text" id="username">
			</td>
		</tr>
		<tr align="center">
			<td>密碼</td>
			<td>
				<input type="password" id="password">
			</td>
		</tr>
		<tr align="center">
			<td colspan="2">
				<input type="submit" value="登錄" id="submit"><br>
				<input type="checkbox" id="auto_login"> 自動登錄<br>
				<span id="span"></span>
			</td>
		</tr>
	</table>
</body>
</html>

3.後臺servlet代碼

package com.gzgs.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gzgs.dao.UserDao;
import com.gzgs.dao.impl.UserDaoImpl;
import com.gzgs.domian.UserBean;

public class AutoLoginServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		try {
			//獲取客戶發過來的值
			String username=request.getParameter("username");
			String password=request.getParameter("password");
			String auto_login=request.getParameter("auto_login");
			System.out.println(username+"====="+password);
			UserBean user=new UserBean();
			user.setUsername(username);
			user.setPassword(password);
			//查詢數據框
			UserDao userDao=new UserDaoImpl();
			UserBean userBean = userDao.findUser(user);
			//判斷所登陸用戶是否存在
			if(userBean!=null) {
				
				//判斷是否選擇自動登錄
				if("on".equals(auto_login)) {
					///發一份cookie給客戶端
					Cookie cookie=new Cookie("auto_login", username+"#"+password);
					//設置7天有效期限
					cookie.setMaxAge(60*60*24*7);
					//設置有效路徑
					cookie.setPath("/autologin");
					response.addCookie(cookie);
				}
				request.getSession().setAttribute("userBean", userBean);
				response.getWriter().write("Login Success");
				
			}else {
				response.getWriter().write("用戶名或者密碼錯誤");
			}
		} catch (SQLException e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

4.過濾器filter代碼

package com.gzgs.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gzgs.dao.UserDao;
import com.gzgs.dao.impl.UserDaoImpl;
import com.gzgs.domian.UserBean;

public class AutoLoginServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		try {
			//獲取客戶發過來的值
			String username=request.getParameter("username");
			String password=request.getParameter("password");
			String auto_login=request.getParameter("auto_login");
			System.out.println(username+"====="+password);
			UserBean user=new UserBean();
			user.setUsername(username);
			user.setPassword(password);
			//查詢數據框
			UserDao userDao=new UserDaoImpl();
			UserBean userBean = userDao.findUser(user);
			//判斷所登陸用戶是否存在
			if(userBean!=null) {
				
				//判斷是否選擇自動登錄
				if("on".equals(auto_login)) {
					///發一份cookie給客戶端
					Cookie cookie=new Cookie("auto_login", username+"#"+password);
					//設置7天有效期限
					cookie.setMaxAge(60*60*24*7);
					//設置有效路徑
					cookie.setPath("/autologin");
					response.addCookie(cookie);
				}
				request.getSession().setAttribute("userBean", userBean);
				response.getWriter().write("Login Success");
				
			}else {
				response.getWriter().write("用戶名或者密碼錯誤");
			}
		} catch (SQLException e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

5.效果展示

在這裏插入圖片描述

在這裏插入圖片描述

完整代碼下載:https://download.csdn.net/download/weixin_45680962/12511580

本博客純屬記錄個人學習筆記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章