javaweb回顾第十二篇监听器

 前言:在web应用中,有时候你想在web应用程序启动或关闭的时候执行一些任务,或者你想见他Session的创建和关闭等你就可以通过监听器来实现。那么Servlet来8个监视器接口,下面一一讲解一下。

1:ServletContextListener和ServletContextAttributeListener

1.1:ServletContextListener主要用于容器的启动和关闭时候进行监听。有2个方法分别用于监听容器启动和关闭。比喻我们在容器启动的时候做数据库连接的初始化。容器关闭时候可以通知从来启动另一个容器保证应用程序的稳定运行

代码如下

public class MyServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Servlet上下文对象开始进行初始化");        
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Servlet上下文对象开始销毁");
    }
}

web.xml配置(下同)

 <listener>
        <listener-class>com.lp.listensrs.MyServletContextListener</listener-class>
 </listener>

1.2:ServletContextAttributeListener主要用来监听上下文对象属性变化的主要有3个方法分别来监听添加属性,删除属性,以及属性值得替代。

public class MyServletContextAttributeListener implements ServletContextAttributeListener{

    public void attributeAdded(ServletContextAttributeEvent scab) {        
        System.out.println("添加的ServletContext属性是"+scab.getName());
    }

    public void attributeRemoved(ServletContextAttributeEvent scab) {
        System.out.println("删除的ServletContext属性是"+scab.getName());
    }

    public void attributeReplaced(ServletContextAttributeEvent scab) {
        System.out.println("属性值进行替代");
    }
}

然后我们在jsp文件上加上

       application.setAttribute("sqlName", "admin");
        application.setAttribute("sqlName", "replaceadmin");
        application.removeAttribute("sqlName");

运行可以看到结果为

2:ServletRequestListener和ServletRequestAttributeListener

2.1:ServletRequestListener主要用来监听httpRequest对象请求和响应的。通过这个监听器可以监听应用程序中每个HTTP请求的数量。代码如下

public class MyServletRequestListener implements ServletRequestListener{
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("对请求进行响应");
    }

    public void requestInitialized(ServletRequestEvent sre) {
        HttpServletRequest request=(HttpServletRequest)sre.getServletRequest();
        String url=request.getRequestURL().toString();
        System.out.println("收到Request请求"+url);
    }
}

然后我们可以看结果

2.1:ServletRequestAttributeListener这个是监听Request属性的变化和ServletContent基本一样。代码如下

public class MyServletRequestAttributeListener implements ServletRequestAttributeListener
{

    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("添加的属性:"+srae.getName());
    }

    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.out.println("删除的属性:"+srae.getName());
    }

    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        String str =MessageFormat.format(
                "ServletRequest域对象中替换了属性:{0}的值"
                ,srae.getName());
        System.out.println(str);
    }
}

3:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener

3.1:HttpSessionListener主要目的是监听Session的创建和消耗的。这里只写一个简单的例子

public class MyHttpSessionListener implements HttpSessionListener{
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("Session创建,Session的Id为"+se.getSession().getId());        
        
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session销毁");
        
    }
}

3.2:HttpSessionAttributeListener、HttpSessionBindingListener这两个我重点说下,前者主要是监听整个应用程序Session属性的变化,而后者主要是自身属性来实现的,以便属性知道他何时添加到一个Session中,或者这个属性从Session删除,(HttpSessionBindingListener并不需要在xml中进行配置)现在来演示这个HttpSessionBindingListener。

我们现在做个简单的在线人数统计。

首先做个userList来存储上线的人数,采用单例模式,同时使用vector来避免线程安全问题。代码如下

public class UserList {

    private static final UserList userList=new UserList();
    private Vector<String> vector;
    public UserList()
    {
        vector=new Vector<String>();
    }
    public static UserList getInstance(){
        return userList;
    }
    public void addUser(String name){
         if(name!=null&&name!=""){
             vector.addElement(name);
         }
    }
    public void removeUser(String name){
        if (name!=null&name!="") {
            vector.remove(name);
        }
    }
    public Enumeration<String> getUserList(){
        return vector.elements();
    }
    public int getUserCount(){
        return vector.size();
    }
}

然后在定义一个UserBean来实现HttpSessionBindingListener从而达到当UserBean对象加入Session时调用valueBound方法删除UserBean对象时候调用valueUnbound方法。

public class UserBean implements HttpSessionBindingListener{

    private String userName;
    private UserList ul=UserList.getInstance();
    public UserBean(){};
    public UserBean(String name){
        this.userName=name;
    }
    public void valueBound(HttpSessionBindingEvent event) {
        ul.addUser(userName);
        System.out.println("被调用");
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        ul.removeUser(userName);
        System.out.println("移除被调用");
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

 然后我们在来定义一个Servlet来用户登录并且把UserBean对象加入Session中如下

public class OnlineUserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public OnlineUserServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String userName=request.getParameter("userName");
        String pwd=request.getParameter("password");
        if (userName==null||userName==""||pwd==null||pwd=="") {
            response.sendRedirect("login.html");
            return;
        }
        HttpSession session=request.getSession();
        UserBean userBean=(UserBean)session.getAttribute("user");
        UserList ul=UserList.getInstance();
        if (userBean==null||!userName.equals(userBean.getUserName())) {
            userBean=new UserBean(userName);
            session.setAttribute("user", userBean);
        }
        response.setContentType("text/html;charset=gb2312");
        PrintWriter out=response.getWriter();
        out.println("欢迎用户<b>"+userName+"</b>登录");
        
        out.println("<br>当前在线用户列表</br>");
        Enumeration<String> enums=ul.getUserList();
        int i=0;
        while (enums.hasMoreElements()) {
            out.println(enums.nextElement());
            out.println("&nbsp;&nbsp;&nbsp;");
            if(i++==10){
                out.println("<br>");
            }
        }
        out.println("<br>当前在线人数:"+i);
        out.println("<p><a href='logout'>退出登录</>");
        out.close();

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

然后在写一个Servlet退出,把UserBean从Session中删除

public class LogOutServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=gb2312");
        HttpSession session=request.getSession();
        UserBean userBean=(UserBean)session.getAttribute("user");
        session.removeAttribute("user");
        PrintWriter out=response.getWriter();
        out.println("<html><head><title>退出登录</title></head><body>");
        out.println(userBean.getUserName()+"你已经退出登录");
        out.println("<a href='index.html'>重新登录</a>");
        out.println("</body></html>");
        out.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

最后写一个index.html登录页面

<form action="online" method="post">
        <table>
            <tr>
                <td>用户名:<input type="text" name="userName" /></td>
                <td>密码:<input type="password" name="password" /></td>
                <td><input type="submit" value="提交" /></td>
            </tr>
        </table>
</form>

先用火狐浏览器登录结婚

然后我在用谷歌浏览器登录

 

posted @ 2016-08-22 22:54  朝向远方  阅读(586)  评论(0编辑  收藏  举报