JavaWeb三大核心主键之------Listener
Listener即监听器的意思,它和Servlet和Filter并称JavaWeb三大核心组件。它的作用就是监听某一个事件的发生或者状态的改变并对此作出反应,它是Servlet规范的另一个高级特性,我们主要通过使用它来监听Java Web程序中的事件,比如创建、修改、删除Session、request、context等,并触发响应的事件。利用Listener能够用很少的代码实现很绚丽的效果,在开发中常用来监听某个servlet被加载,然后做一些初始化得工作。
它的内部机制就是接口回调,这里就引入一个新的概念,何为接口回调?
理解接口回调
简单来说接口回调就是可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。它充分的体现了java多态的特性,下面是关于接口回调的例子图。
Listener总共有8个,根据其监听的对象或功能又可以分为三种类型:
- 监听三个作用域创建和销毁
- ServletContextListener
- ServletRequestListener
- HttpSessionListener
- 监听三个作用域属性状态变更
- ServletContextAttributeListener
- ServletRequestAttributeListener
- HttpSessionAttributeListener
- 监听httpSession里面存值的状态变更
- HttpSessionBindingListener
- HttpSessionActivationListener
监听三个作用域创建和销毁
这三个作用域就是request 、session、aapplication
-
ServletContextListener—监听servletContext的创建和销毁
servletcontext创建: 启动服务器的时候
servletContext销毁:关闭服务器. 从服务器移除项目 -
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>
-
HttpSessionListener----监听session的创建和销毁
session的创建:只要调用getSession
访问jsp和servlet时候就会创建sessionsession的销毁: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?
-
定义一个类, 实现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.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
本博客纯属记录个人学习笔记