监听器

  • 监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听别一个类的方法调用。
  • 什么是观察者模式:
定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。 
GUI编程中的addXxxxListener都是观察者模式。

Java监听Controller 返回_servlet

观察者设计模式示例:
开发步骤:
* 第一步:实现一个需要被监听的类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)

Java监听Controller 返回_servlet_02

其他两个监听器-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–>过滤器–>监听器.