Listener介绍
介绍
listener(听众)
在Java中通常指的是监听器。
作用?
一般是监听某一个事情的 发生,或者状态的改变等。
监听器的内部机制?
其实就是接口回调。
监听器的内部实现就是接口回调:
例子分析 :
需求,需要在一个A类的方法中循环10 当循环到了5打印一下到 了5 就传给B类 。
传统方式:
A类
public class A{
public void print(){
for(int i=0;i<=10;i++){
System.out.print("现在打印的是:"+i);
if(i==5){
System.out.print("现在打印到了5 传递给B类");
B b=new B();
b.printFive();
}
}
}
}
B类
public class B{
public void piintFive(){
System.out.print("我是B类");
}
}
结果:
这里注意到在A类中,要先创建B类对象,在调用其方法,但是一般实际例子中比如使用开发框架的时候有的方法在 以前就已经定义好了,所以 并不能直接在A类中写创建B类对象的代码,所以应该使用接口回调方法,看下文例子。
接口回调方法实现:
建立一个Test 接口类
public interface Test{
void Listener();
}
实现其Test类方法
public B implements Test{
void Listener(){
System.out.print("这是实现Test 类的接口方法 B类 ")
}
}
改造A类方法
public class A{
public void print(Test t){
for(int i=0;i<=10;i++){
System.out.print("现在打印的是:"+i);
if(i==5){
System.out.print("现在打印到了5 传递给B类");
t.Listener();
}
}
}
}
建立一个测试C类
public class C{
@Test
public void print(){
A a=new A();
a.print(new B());
}
}
结果:
图解:
1.在A的对象小a 中调用 A类的print方法
2.在调用方法的时候把接口实现类B 传过去(这里 new B体现了多态.)
3.在A类中执行B类的方法.从而实现了接口调用!
web监听器
总共有8个 划分为三种类型。
使用方法:
- 定义一个类,实现一个接口
- 注册xml 配置监听器
一类:监听三个作用域的创建和销毁
- request --httpservletrequest
- session --httpsession
- application --ServletContext
1.ServletConTextListener
servletcontext创建: 启动tomcat服务器的时候
servletcontext销毁: 关闭服务器 服务器移除的时候
例子:
MyServletContextListener.java
package com.web.st.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener{
//初始化的时候调用
@Override
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("这是一个监听器的创建.....");
}
//销毁的时候调用
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("这是一个监听器的销毁.....");
}
}
web.xml
<listener>
<listener-class>com.web.st.listener.MyServletContextListener</listener-class>
</listener>
结果:
关闭服务器:
2.ServlertRequestListener
servletrequestlistener创建: JSP,HTML,request
这三个都会在被访问的时候 都会创建,其实在服务器上任意资源被访问都会创建
servletrequestlistener销毁: 服务器已经对这次访问做出了响应
例子:
MyServletRequstListener.java
package com.web.st.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyServletRequstListener implements ServletRequestListener{
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
System.out.println("这是servletrequestlistener被销毁了....");
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
// TODO Auto-generated method stub
System.out.println("这是servletrequestlistener被创建了....");
}
}
Servlet.java
package com.web.st.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
web.xml
<servlet>
<description></description>
<display-name>Servlet</display-name>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.web.st.servlet.Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/Servlet</url-pattern>
</servlet-mapping>
index.jsp
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
这是jsp页面
</body>
</html>
结果:
3.HttpSessionListener
httpsessionlistener的创建: 只要调用getsession就会创建
html 不会
jsp 会
servlet会
httpsessionlistener的销毁: 超时,30min 非正常关闭销毁 正常关闭服务器(序列化)
例子:
MyHttpSessionListener.java
package com.web.st.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.catalina.SessionListener;
public class MyHttpSessionListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("这是httpsessionlistener的创建...");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("这是httpsessionlistener的销毁...");
}
}
servlet.java
req.getSession();
web.xml
<listener>
<listener-class>com.web.st.listener.MyHttpSessionListener</listener-class>
</listener>
同样在这里写一个 index.html
<body>
这是html页面
</body>
结果:
这里不会打印,当访问servlet时 调用getsession 方法就会打印:
作用:
servletcontextlistener
利用他来在servletcontext创建的时候:
- 完成自己想要的初始化工作
- 执行自定义任务调度。执行某一个任务的时候 做一个定时器。
httpsessionlistener
- 统计在线人数等
(serverletrequestlistener 这个不常用)
二类:监听三个作用域的状态变更
可以监听在作用域中值 添加 替换 移除的动作
request —ServletRequestAttributeListener
session–HttpsessionAttributeListener
servletcontext–ServletContextAttributeListener
例子:
attbutribute.java
package com.web.st.listener02;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class attbutribute implements HttpSessionAttributeListener{
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被添加进来了...");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被移除了...");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("属性被替换了...");
}
}
index.jsp
<body>
<%
session.setAttribute("name", "zhangsan");
session.setAttribute("name", "lisi");
session.removeAttribute("name");
%>
</body>
web.xml
<listener>
<listener-class>com.web.st.listener02.attbutribute</listener-class>
</listener>
结果:
三类:监听httpsession里面存值的状态变更
这一类监听器不用注册
- HttpSessionBindingListener
监听对象与session 绑定和解除绑定的动作
1.让JavaBean实现该接口即可
例子:
user.java
package com.web.st.bean;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class user implements HttpSessionBindingListener{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("对象被绑定了....");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub
System.out.println("对象解除绑定了....");
}
}
index.jsp
<%
user u=new user();
u.setName("张三");
session.setAttribute("bean", u);
session.removeAttribute("bean");
%>
这里 不必注册web.xml
结果:
- HttpSessionActivationListener
用于监听现在session的值是钝化(序列化)还是活化(反序列化)的动作
-
钝化(序列化)
把内存中的数据 存储到硬盘上 -
活化(反序列化)
把硬盘中的数据读取到内存中。
(钝化)例子:
MyHttpSessionListener1.java
package com.web.st.listener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
public class MyHttpSessionListener1 implements HttpSessionActivationListener{
@Override
public void sessionDidActivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session中的值被活化了呀....");
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session中的值被钝化了呀....");
}
}
users.java
package com.web.st.bean;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
public class users implements HttpSessionActivationListener ,Serializable{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session中的值被活化了....");
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
// TODO Auto-generated method stub
System.out.println("session中的值被钝化了....");
}
}
index.jsp
<%
users bean=new users();
bean.setName("lisi");
session.setAttribute("bean", bean);
%>
无需 注册web.xml 直接启动服务器 :
访问index.jsp
关闭服务器:
可以在tomcat 以下路径找到存的:
(活化)例子:
先关闭服务器 在重启 服务器 :
结果
- session的钝化活化的作用:
- session中的值可能会很多,并且我们有很长一段时间不使用这个内存中的值,那么可以考虑把session的值可以存储到硬盘上 即钝化,等下一次在使用的时候,在从硬盘上提取出来即活化。
- 如何让session在一定时间内钝化
可以做 配置!
- 在tomcat里面 conf/context.xml里面配置
对所有的运行在这个服务器的项目生效 - 在conf/Catalina/localhost/context.xml配置
对localhost下列的路径生效.localhost:8080 - 在自己的web工程项目中的 META-INF/context.xml
只对当前的工程生效
maxIdleSwap=“1” 代表 配置的时间 一分钟不用就钝化
directory=“web” 代表存放的目录位置
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="web"/>
</Manager>
</Context>