JSP&Servlet5(二) --- 应用程序事件 监听器

来源:互联网 发布:化学动画软件 编辑:程序博客网 时间:2024/06/05 18:34

Web容器管理Servlet/JSP相关的对象生命周期, 若对HttpSession对象/ServletContext对象在生成, 销毁或相关属性设置(或改变)发生的时机感兴趣, 则可以实现对应的监听器(Listener).


1. ServletContext事件 监听器

与ServletContext事件相关的监听器有:

  • 生命周期监听器: ServletContextListener
  • 属性改变监听器: ServletContextAttributeListener

(1) ServletContextListener

1> ServletContextListener概述:

ServletContexListener接口是继承于EventListener接口, 主要用于知道Web应用程序何时已经初始化或即将结束销毁. 其中实现了contextInitialized()方法和contextDestroyed()方法, 分别在应用程序初始化后或即将结束前调用这两个方法.ServletContextListener接口的实现代码如下:

public interface ServletContextListener extends EventListener{    public void contextInitialized(ServletContextEvent sce);    public void contextDestroyed(ServletContextEvent sce);}//ServletContextEvent中封装了ServletContext, 可以通过getServletContext()方法来获得

2> ServletContextListener的使用说明

例: 在应用程序初始化过程中, 应该准备好数据库链线对象, 读取应用程序设置等动作, 如放置头像的目录信息, 是整个应用程序中的Servlet应该共享的数据, 不应该直接写死在每一个Servlet中. 假设日后需要修改, 则需要在每一个Servlet中去修改. 所以可以将目录设置为ServletContext的属性, 因为ServletContext在Web应用程序存活期间都会存在. 具体实现的部分代码如下:

实现ServletCotextListener接口

//本段代码实现ServletContextListener接口, 并对初始化操作的方法进行重定义@WebListener    //WebListener标注没有设置初始化参数的属性, 若需设置初始参数, 则应在web.xml中进行设置://<context-param>//<param-name>AVATAR_DIR</param-name>//<param-value>/avatars</param-value>//</context-param>public class ContextParameterReader implements ServletContextListener{    public void contextInitialized(ServletContextEvent sce){    ServletContext context = sce.getServletContext();    //取得ServletContext对象    String avatars = context.getInitParamer("AVATAR_DIR");    //取得初始参数    context.setAttribute("avatars", avatars);    //设置ServletContext属性    }    public void contextDestroyed(ServletContextEvent sce){};}

在具体的Servlet中应用该监听器

@WebServlet("/avatar.view")//仅设置URL模式, 而不必要设置该Servlet的initParams(初始化参数)public class Avatar extends HttpServlet{    private String AVATAR_DIR;    @Override    public void init() throws ServletException{        AVATAR_DIR = (String)getServletContext().getAttribute("AVATAR_DIR");        //这样就可以直接获取到整个Web应用程序中设置的ServletContext属性, 整个Web应用程序的所有Servlet都可以共享具有该属性的数据, 而不用在每个Servlet中先设置初始化参数再取得初始化参数    }}

(2) ServletContextAttributeListner

1> ServletContextAttributeListner概述

ServletContextAttributeListner继承与EventListener接口, 是监听属性改变的监听器, 如果想要对象在被设置/移除/或替换ServletContext属性时可以收到通知以进行一些其他的操作, 可以实现该接口. 该接口主要实现了三个方法:atrributeAdded(), atrributeRemoved(), attributeReplace(), 当在ServletContext中添加属性/移除属性/替换属性时, 就会调用相应的方法. ServletContextAttributeListner接口的代码如下:

public interface ServletContextAttributeListner extends EventListener{    public void attributeAdded(ServletContextAttributeEvent scae);    public void attributeRemoved(ServletContextAttributeEvent scae);    public void attributeReplaced(ServletContextAttributeEvent scae);}

2> ServletContextAttributeListner的使用说明

ServletContextAttributeListner的使用与ServletContextListener的使用大致相同, 在用法这里不过多赘述.

2. HttpSession事件 监听器

JSP&Servlet中使用HttpSession来进行会话管理, 所谓会话管理, 就是记得此次会话与之后会话的关系. 将会话期间需要共享的数据保存在HttpSession中成为属性.

(1) HttpSessionListener

1> HttpSessionListener概述

HttpSessionListener接口继承与EventListener接口, 是HttpSession的生命周期监听器. 如果想要在HttpSession对象创建或结束时, 做些相应操作, 则可以实现HttpSessionListener接口. 该接口主要有两个方法: sessionCreated()方法和sessionDestroyed()方法. HttpSessionListener接口的代码如下:

public interface HttpSessionListener extends EventListener{    public void sessionCreated(HttpSessionEvent se);    public void sessionDestroyed(HttpSessionEvent se);//可以通过传入的HttpSessionEvent的getSession()取得HttpSession对象}

2> HttpSessionListener的使用说明

例: 有些网站为了防止用户重复登录, 会在数据库中设立一个字段来代表用户是否已经登录, 而用户注销后, 就会重置该字段. 现在有一个问题, 假设用户并没有正确注销帐号, 而是直接关闭了浏览器, 那么该帐号应该如何被正确注销并在数据库中正确重置登录字段呢?
因为HttpSession有其存活期限, 当用户没有注销而关闭浏览器后, 一段时间后, 该登录令牌会自动失效, 所以可以实现HttpSessionListener接口, 在HttpSession失效前检测并重置登录字段.
实现HttpSessionListener接口代码如下:

@WebListener()public class ResetLoginHelper implements HttpSessionListener{    @Override    public void sessionCreated(HttpSessionEvent se){}    @Override    public void sessionDestroyed(HttpSessionEvent se){        HttpSession session = se.getSession();        String user = session.getAttribute("login");        //修改数据库中登录字段为注销状态    }}

(2) HttpSessionAttributeListener

1> HttpSessionAttributeListener概述

HttpSessionAttributeListener继承于EventListener接口, 是属性改变监听器, 当会话对象中加入/移除/替换属性时, 相对应的attributeAdded()/attributeRemoved()/attributeReplaced()方法就会被调用. HttpSessionAttributeListener接口的代码如下:

public interface HttpSessionAttributeListener extends EventListener{    public void attributeAdded(HttpSessionBindingEvent se);    public void attributeRemoved(HttpSessionBindingEvent se);    pubic void attributeReplaced(HttpSessionBindingEvent se);    //HttpSessionBindingEvent中的getName()方法可以获得属性的名称, getValue()方法可以获得属性的值.}

(3) HttpSessionBindingListener

1> HttpSessionBindingListener概述

HttpSessionBindingListener继承于EventListener接口, 是对象属性监听器, 如果有个即将加入HttpSession的属性对象, 希望在设置给HttpSession成为属性或者从HttpSession中移除时, 可以收到HttpSession的通知, 则可以让该对象实现HttpSessionBindingListener接口. 该接口有两个方法:valueBound()和valueUnbound(), 分别在对象加入HttpSession或移除时被调用, 该接口的代码如下:

public interface HttpSessionBindingListener extends EventListener{    public valueBound(HttpSessionBindingEvent event);    public valueUnbound(HttpSessionBindingEvent event);    //可以通过HttpSessionBindingEvent对象的getSession()方法取得HttpSession对象.}

2> HttpSessionBindingListener的使用说明

例: 假设在用户登录程序中, 当用户输入正确的用户名和密码时, 会创建User类的实例, 希望在成为User类的实例时被加入成为HttpSession属性时, 可以自动从数据库中加入所需要的用户的其他数据, 比如地址照片等, 所以可以让User类来实现HttpSessionBindingListener接口.

User类的实现代码如下:

public class User implements HttpSessionBindingListener{    private String name;    private String data;    public User(String name){        this.name = name;    }    public void valueBound(HttpSessionBindingEvent event){        this.data = name + "来自数据库的数据...";    }    public void valueUnbound(HttpSessionBindingEvent event){}    public String getData(){        return data;    }    public String getName(){        return name;    }}

在Servlet中应用实现了HttpSessionBindingListener接口的User类的代码如下:

@WebServlet("/login.do")public class Login extends HttpServlet{    ...    @Override    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{        ...        String page = "form.html";        //containsKey(name):判断是否存在此键名        if(users.containsKey(name) && users.get(name).equals(passwd)){            User user = new User(name);         request.getSession().setAttribute("user", user);            page = "welcome.view";                  }        response.sendRedirect(page);    }}

(4) HttpSessionActivationListener

1> HttpSessionActivationListener概述

HttpSessionActivationListener是对象迁移监听器, 一般不会用到该监听器, 只有在使用到分布式环境时, 应用程序的对象可能分散在多个JVM中.

3. HttpServletRequest事件 监听器

(1) ServletRequestListener

1> ServletRequestListener概述

ServletRequestListener是请求对象的生命周期监听器, 继承于EventListener接口, 其中定义了两个方法:requestInitialized()和requestDestroyed()方法, 分别在请求初始化或结束之前被调用. ServletRequestListener接口的代码如下:

public interface ServletRequestListener extends EventListener{    public void requestInitialized(ServletRequestEvent sre);    public void requestDestroyed(ServletRequestEvent sre);    //可以通过传入的ServletRequestEvet对象的getRequest()方法来取得ServletRequest对象.}

2> ServletRequestListener的使用说明

例: 假设有一个Servlet希望子请求创建或销毁时做一些动作, 则可以实现ServletRequestListener接口, 其代码如下:

public class SomeRequest implements ServletRequestListener{    ...}

(1) ServletRequestAttributeListener

1> ServletRequestAttributeListener概述

ServletRequestAttributeListener是请求对象的属性改变监听器, 其继承于EventListener接口, 主要有三个方法:attributeAdded()/attributeRemoved()/attributeReplace(), 分别在属性添加/移除/替换时被调用. ServletRequestAttributeListener接口的代码如下:

public interface ServletRequestAttributeListener extends EventListener{    public void attributeAdded(ServletRequestAttributeEvent sre);    public void attributeRemoved(ServletRequestAttributeEvent sre);    public void attributeReplace(ServletRequestAttributeEvent sre);    //ServletRequestAttributeEvent有getName()方法来取得属性指定的名称, getValue()方法来取得属性的值.值}
  • 生命周期监听器与属性改变监听器都必须使用@WebListener标注, 或在web.xml中进行设置, 这样容器才会知道要加载读取监听器相关设置.