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

本博客纯属记录个人学习笔记
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空圆小生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值