监听器
- 监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听别一个类的方法调用。
- 什么是观察者模式:
定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
GUI编程中的addXxxxListener都是观察者模式。
观察者设计模式示例:
开发步骤:
* 第一步:实现一个需要被监听的类Cat.
* 第二步:实现一个监听接口ICatListener。
* 第三步:在Cat类中,提供一个方法用于注册ICatListener类,即ICatListener
* 第四步:必须要在Cat类中维护ICatListener类的实例。
* 第五步:在调用Cat.climb方法是,判断ICatListener是否为null,如果不为null则调用它的climb方法。
* 第六步:在Main类中,实例化Cat,并注册一个监听。
给观察者模式-添加事件源:
开发步骤:
第一步:在前页的基础上继续添加一个CatEvent类(注意我说是類不是接口),代表事件对像。
第二步:给CatEvent对像,添加一个Object属性,用以标识事件源对像。
第三步:修改ICatListener接口的climb方法,让它接收一个CatEvent参数。
第四步:在Cat类climb方法中,如果判断ICatListener属性不为空,则在调用climb方法,实例化CatEvent并传给eating方法。
第五步:在main方法中,通过CatEvent的getSource方法测试是否是同一个对像。
package cn.hncu.designPattern.two;
public class Cat {
private String name;
private ICatListener listener;
private String actionCommand;
public Cat(String name) {
this.name = name;
}
public void climb(){
System.out.println(name+"好调皮,在爬");
if(listener!=null){
listener.help(new CatEvent(this));//传自己
}
}
public void addCatlistener(ICatListener listener ){
this.listener=listener;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setActionCommand(String actionCommand) {//获得命令
this.actionCommand = actionCommand;
}
public String getActionCommand() {
return actionCommand;
}
@Override
public String toString() {
return name;
}
}
interface ICatListener{
public void help(CatEvent e);
}
class CatEvent{
private Cat cat;
private String actionCommand;
public CatEvent(Cat cat) {
this.cat = cat;
actionCommand=cat.getActionCommand();//actionCommand在这进行判断
}
public Object getSource(){
return cat;
}
public String getActionCommand() {
return actionCommand;
}
}
class DeFaultCatListener implements ICatListener{
@Override
public void help(CatEvent e) {
System.out.println("这是默认猫做的事");
}
}
Servlet技术的监听器(查看API)
其他两个监听器-1:
HttpSessionBindingListener
实现此接口类的类,不必在web.xml中进行配置。
实现此接口的类,通常是一个JavaBean,一个JavaBean通过实现此接口,可以感知自己是否添加到了Session中。或是感知自己是否从Session中移除。
示例:
public class Person implements HttpSessionBindingListener {
public void valueBound(HttpSessionBindingEvent arg0) {
System.err.println("我被添加到了Sesion中"+arg0.getName());
}
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.err.println("我从Session中被移除了....");
}
}
其他两个监听器-2-会话的持久化:
HttpSessionActivationListener
实现此接口的JavaBean,可以感知自己被活化(从硬盘到内存)和钝化(从内存到硬盘)的过程。
如果需要同时保存Session中的JavaBean则JavaBean也要实现Serializable序列化接口。
实现此接口的JavaBean与HttpSessionBindingListener一样,不必配置到web.xml中。
要实现此功能,必须要先配置以下信息:
第一步:书写一个JavaBean,并实现HttpSessionActivationListener接口如下:
package cn.hncu.domain;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
public class Person implements Serializable,HttpSessionActivationListener {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name) {
super();
this.name = name;
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("保存到硬盘上");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("从硬盘上读取");
}
@Override
public String toString() {
return "Person [name=" + name + "]"+super.toString();
}
}
第二步:JSP页面,判断是否存在Person,如果没有将Person放到Session中:
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="cn.hncu.domain.Person"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<% if(session.getAttribute("p")==null){
Person p=new Person("Jack");
session.setAttribute("p", p);
}
System.out.print(session.getId());
System.out.print(session.getAttribute("p"));
long time=session.getCreationTime();
Date d=new Date(time);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.print(sdf.format(d));
System.out.print("______________________");
%>
</body>
</html>
第三步:配置Tomcat的Server.xml文件或是将配置好的xml发布文件放到CATALIINA_HOME\conf\Catalina\localhost目录下:
第四步:测试
1:多次开启新的浏览器窗口,并记录SESSIONID。
2:使用shutdown.bat关闭tomcat应用。
3:观察指定的目录下是否存在*.session文件。
4:再次重新启动tomcat,并使用http://localhost:8080/project;jsessionid=xxxxx指定sessionid的方式访问服务器。
5:观察是否为关闭tomcat之前的同一个Session。
6:一般情况下,PersistentManager持久化Session与Cookie共同使用。
7:HttpSessionActivationListener只做为监听类,监听自己是否钝化或是活化。
“`
Servlet、过滤器、监听器实例化对象的优先级和销毁的优先级
创建(初始化): (ServletContext) 监听器–>过滤器–>Servlet.
调用时候:过滤器–>监听器–>Servlet.
销亡:Servlet–>过滤器–>监听器.