zoukankan      html  css  js  c++  java
  • 第六章 对象作用域与servlet事件监听器

     
     
     
    作用域对象
    Servlet上下文监听器
    Servlet会话监听器
    Servlet请求监听器
     
     
    一:对象作用域

    作用域对象

    属性操作方法

    作用域范围说明

    ServletContext(上下文)

    void setAttribute(String, Object)

    Object getAttribute(Sting)

    void removeAttribute(String)

    Enumeration getAttributeNames()

    整个Web应用程序

    HttpSession(会话)

    一个会话交互过程

    ServletRequest(请求)

    一次请求过程

    1.1ServletContext应用上下文
    例子:页面访问量的统计程序
    主要的代码块:
     1         ServletContext sc=getServletContext();
     2         Integer count=(Integer)sc.getAttribute("counter");
     3         if(count==null){
     4             count=new Integer(1);
     5         }else{
     6             count=new Integer(count.intValue()+1);
     7         }        
     8         sc.setAttribute("counter", count);    
     9         resp.getWriter().print("该页面被访问的次数是:"+count);
    10         resp.getWriter().close();

     

    提示:上下文作用域中设置的属性在整个Web应用中被共享,只要服务器不被关闭,Web应用中任何一部分都能访问到该属性。所以线程是不安全的。

    1.2 HttpSession 会话作用域

    例子:在线多人登录

    主要的代码块:

    count

     1         PrintWriter pw=resp.getWriter();        
     2         ServletContext sc=getServletContext();
     3         HttpSession sess=req.getSession();
     4         String name = req.getParameter("username");
     5         List<String> userList=(List) getServletContext().getAttribute("userList");        
     6         if(userList==null){
     7             userList=new ArrayList<String>();
     8         }
     9         if(name!=null){
    10             name=new String(name.getBytes("iso-8859-1"),"utf-8");
    11             System.out.println("================="+name);
    12             userList.add(name);
    13             sess.setAttribute("username",name);
    14             getServletContext().setAttribute("userList", userList);
    15             req.getRequestDispatcher("/count1").forward(req, resp);
    16             
    17         }
    18         else{
    19             pw.print("<html>");
    20             pw.print("<head></head>");
    21             pw.print("<body><h1>在线书店登录</h1>");
    22             pw.print("<form action='/day13/count'>");
    23             pw.print("username:<input type='text' name='username'/><br/>");
    24             pw.print("<input type='submit' value='submit'/></form></body>");
    25             pw.print("</html>");            
    26         }
    27         pw.flush();
    28         pw.close();
    29         

     count1

     1  PrintWriter pw=resp.getWriter();          
     2           HttpSession sess=req.getSession();
     3           List<String> userList=(List) getServletContext().getAttribute("userList");
     4           String name=(String) sess.getAttribute("username");
     5           String action=req.getParameter("action");
     6           if(action==null){
     7                pw.print("用户"+name+"欢迎你!【<a href='count1?action=loginout'>注销</a>】<br/>");
     8                Iterator<String> i=userList.iterator();
     9                while(i.hasNext()){
    10                    String name1=i.next();
    11                    pw.print("<p>当前用户有:"+name1+"</p>");
    12                }
    13                
    14           }else if(action.equals("loginout")){
    15               sess.invalidate();
    16               userList.remove(name);
    17               getServletContext().setAttribute("userList", userList);
    18               
    19           }        
    20         
        
     
    提示:每一个会话只能访问当前会话作用域中设置的属性。但是当我们使用特殊的浏览器窗口打开方式使用相同的Session来访问该设置的属性。也就是说多个线程访问相同的会话属性。所以线程也是不安全的。
     
    1.3  ServletRequest 请求作用域
    系统的资源消耗
    属性可以保存在请求作用域范围中
     
     
     
    二:监听器概述
    监听session,request,application这三个对象里存取数据的变化
    监听器对象可以在事情发生前、发生后可以做一些必要的处理
    Servlet监听器主要目的是给Web应用增加事件处理机制,以便更好地监视和控制Web应用的状态变化
          Servlet监听器接口和相对应的监听器事件类

    事件类型

    描述

    Listener接口

    ServletContext   事件

    生命周期

    Servlet上下文刚被创建并可以开始为第一次请求服务,或者Servlet上下文将要被关闭发生的事件

    ServletContextListener

    属性改变

    Servlet上下文内的属性被增加、删除或者替换时发生的事件

    ServletContextAttributeListener

    HttpSession    事件

    生命周期

    HttpSession被创建、无效或超时时发生

    HttpSessionListener

    HttpSessionActivationListener

    会话迁移

    HttpSession被激活或钝化时发生

    属性改变

    在HttpSession中的属性被增加、删除、替换时发生

    HttpSessionAttributeListener

    HttpSessionBindingListener

    对象绑定

    对象被绑定到或者移出HttpSession时发生。

    ServletRequest   事件

    生命周期

    在Servletr请求开始被Web组件处理时发生

    ServletRequestListener

    属性改变

    在ServletRequest对象中的属性被增加、删除、替换时发生

    ServletRequestAttributeListener

    三:监听Web应用程序范围内的事件

    Web应用启动和销毁事件
    Web应用程序的属性发生改变的事件(包括增加、删除、修改)。
    定义了ServletContextListener和ServletContextAttributeListener两个接口

    监听器需要在web.xml定义监听器: 

    <listener>
             <listener-class>com.cy.listener.servletContext</listener-class>
    </listener>

    1)ServletContextListener接口的方法如下:
    例子:由监听器管理共享数据库连接
     1 package com.cy.listener;
     2 
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 import java.sql.SQLException;
     6 
     7 import javax.servlet.ServletContextEvent;
     8 import javax.servlet.ServletContextListener;
     9 
    10 public class ServletContext implements ServletContextListener {
    11 
    12     @Override
    13     public void contextDestroyed(ServletContextEvent arg0) {
    14         //应用程序被销毁
    15         try {
    16             Connection c=(Connection) arg0.getServletContext().getAttribute("connection");
    17             c.close();
    18         } catch (SQLException e) {
    19             
    20             e.printStackTrace();
    21         }
    22         
    23     }
    24 
    25     @Override
    26     public void contextInitialized(ServletContextEvent arg0) {
    27         //应用程序被加载及初始化
    28          try {
    29              //连接数据库
    30             Class.forName("com.mysql.jdbc.Driver");
    31             Connection con=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/books","root","root");
    32             arg0.getServletContext().setAttribute("connection", con);
    33         } catch (Exception e) {
    34             e.printStackTrace();
    35         }
    36          
    37     }
    38 
    39 }

     2)ServletContextAttributeListener接口方法:

     1 package com.cy.listener;
     2 
     3 import javax.servlet.ServletContextAttributeEvent;
     4 import javax.servlet.ServletContextAttributeListener;
     5 
     6 public class MyServletContext implements ServletContextAttributeListener {
     7 
     8     @Override
     9     public void attributeAdded(ServletContextAttributeEvent event) {
    10         System.out.println("添加一个ServletContext属性"+event.getName()+"========="+event.getValue());//回传属性的名称  值
    11     }
    12 
    13     @Override
    14     public void attributeRemoved(ServletContextAttributeEvent event) {
    15         System.out.println("删除一个ServletContext属性"+event.getName()+"========="+event.getValue());
    16     }
    17 
    18     @Override
    19     public void attributeReplaced(ServletContextAttributeEvent event) {
    20         System.out.println("某个ServletContext属性被改变"+event.getName()+"========="+event.getValue());
    21     }
    22 
    23 }
     1 package com.cy.listener;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 public class Test extends HttpServlet{
    11     
    12     private static final long serialVersionUID = 1L;
    13 
    14     @Override
    15     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    16             throws ServletException, IOException {
    17         resp.setContentType("text/html;charset=utf-8");
    18         getServletContext().setAttribute("username", "tiger");
    19         getServletContext().setAttribute("username", "kitty");
    20         getServletContext().removeAttribute("username");        
    21     }
    22     
    23     @Override
    24     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    25             throws ServletException, IOException {
    26         doPost(req, resp);
    27     }
    28 
    29 }

     结果:

    添加一个ServletContext属性username=========tiger
    某个ServletContext属性被改变username=========tiger
    删除一个ServletContext属性username=========kitty

    四:监听会话范围内事件
    1)HttpSessionBindingListener接口
    注意:HttpSessionBindingListener接口是唯一不需要在web.xml设定的listener;
    当我们的类实现了HttpSessionBindingListener接口后,只要这个对象加入Session范围(即调用HttpSession对象的setAttribute方法的时候)或从Session对象移出(即调用HttpSession对象的removeAttribute方法的时候或Session超时时)容器就会通知这个对象,分别会自动调用下列两个方法:
    –void valueBound(HttpSessionBindingEvent event):当对象正在绑定到Session中,Servlet容器调用该方法来通知该对象
    –void valueUnbound(HttpSessionBindingEvent event):当从Session中删除对象时,Servlet容器调用该方法来通知该对象

    HttpSessionBindingEvent类提供如下方法:

    public String getName():返回绑定到Session中或从Session中删除的属性名字。

    public Object getValue():返回被添加、删除、替换的属性值

    public HttpSession getSession():返回HttpSession对象

     
     
    2)HttpSessionAttributeListener接口
    监听HttpSession中的属性的操作
    –当在Session中增加一个属性时,激发attributeAdded(HttpSessionBindingEvent event) 方法;
    –当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent event)方法;
    –当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent event) 方法。 
     
     3)HttpSessionListener接口
    监听HttpSession对象的创建和销毁操作
    -当创建一个Session时,激发session Created(HttpSessionEvent event)方法
    –当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent event)方法
    例子:可用于在线人数的统计
    主要代码:
     1 package com.cy;
     2 
     3 public class OnlineCounter {
     4     private static int online=0;
     5     
     6     public static int getOnlie(){
     7         return online;        
     8     }
     9     public static void raise(){
    10         online++;
    11     }
    12     public static void reduce(){
    13         online--;
    14     }
    15 
    16 }
    17 
    18 
    19 package com.cy;
    20 
    21 import javax.servlet.http.HttpSessionEvent;
    22 import javax.servlet.http.HttpSessionListener;
    23 
    24 public class OnlineConter  implements HttpSessionListener{
    25 
    26     @Override
    27     public void sessionCreated(HttpSessionEvent arg0) {
    28         OnlineCounter.raise();    
    29     }
    30     @Override
    31     public void sessionDestroyed(HttpSessionEvent arg0) {
    32       OnlineCounter.reduce();        
    33     }
    34 
    35 }
    36 
    37 
    38 package com.cy;
    39 
    40 import java.io.IOException;
    41 
    42 import javax.servlet.ServletException;
    43 import javax.servlet.http.HttpServlet;
    44 import javax.servlet.http.HttpServletRequest;
    45 import javax.servlet.http.HttpServletResponse;
    46 import javax.servlet.http.HttpSession;
    47 
    48 public class TestServlet extends HttpServlet {
    49     @Override
    50     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    51             throws ServletException, IOException {
    52         resp.setContentType("text/html;charset=utf-8");
    53         HttpSession sess=req.getSession();
    54         sess.setMaxInactiveInterval(10);
    55         resp.getWriter().print("当前在线人数为:"+OnlineCounter.getOnlie());        
    56     }
    57     
    58     @Override
    59     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    60             throws ServletException, IOException {
    61         doPost(req, resp);
    62     }
    63     
    64 
    65 }

    五:监听请求生命周期内事件

    请求作用域范围内的生命周期事件用于管理整个request生命周期的状态和资源
    ServletRequestListener接口
    –public void requestDestroyed(ServletRequestEvent event):当请求被销毁时被处理。
    –public void requestInitialized(ServletRequestEvent event):当请求被创建时被处理
    ServletRequestAttributeListener接口
    –public void attributeAdded(ServletRequestAttributeEvent event) :当在请求作用域中添加一个属性的时候调用该方法。
    –public void attributeRemoved(ServletRequestAttributeEvent event) :当在请求作用域中删除一个属性时调用
    –public void attributeReplaced(ServletRequestAttributeEvent event) :当在请求作用域中替换一个属性值的时候调用
     
    总结:
    1 在Servlet中3个对象作用域分别由ServletContext、ServletRequest和HttpSession接口来处理
    2 上下文作用域中设置的属性是线程不安全的
    3 对于同一个客户的多个请求,Session会跨这些请求持久存储
    4 设置在上下文和会话作用域中的对象,会非常消耗系统的资源
    5 请求作用域范围仅仅作用在与一个请求相关的两个资源之间
    6 应用程序事件监听器是实现一到多个Servlet事件监听器接口的类。它们在Web应用程序部署的时候,被Web容器初始化和注册
    7 ServletContext监听器用于管理应用程序JVM级别保存的资源或状态。
    8 HTTP会话监听器用于管理从同一客户端或用户发送的一系列请求的资源或状态。
    9 Request请求监听器用于管理Request请求生命周期内的状态  
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    跟我从零基础学习Unity3D开发--资源打包篇(AssetBundle)
    跟我从零基础学习Unity3D开发--U3d脚本注意事项及两个基本函数的简单介绍
    跟我从零基础学习Unity3D开发--初识U3D
    关于把.net 2.0的项目升级到.net4.0遇到的一些问题
    反射在ADO.NET中的运用(你还在每个项目中循环遍历DataTable吗)
    您还在招聘网上海量投简历然后等面试机会吗?那你已经OUT了。
    程序员其实也有感情的,不是我们无情,是您关怀不够。
    C#程序员的春天之从零开始学习unity3D游戏开发入门教程二(创建项目及基本面板介绍)
    C#程序员的春天之从零开始学习unity3D游戏开发入门教程一(前言)
    跟我从零基础学习Unity3D开发--Unity3D开发必备神器(Visual Studio Tools for Unity)
  • 原文地址:https://www.cnblogs.com/hellokitty1/p/4923088.html
Copyright © 2011-2022 走看看