第六章 对象作用域与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请求生命周期内的状态  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

时间: 2024-10-31 18:11:45

第六章 对象作用域与servlet事件监听器的相关文章

《快学Scala》第六章 对象 第七章 包和引入

本文转自博客园xingoo的博客,原文链接:<快学Scala>第六章 对象 第七章 包和引入,如需转载请自行联系原博主.

Android群英传笔记——第六章:Android绘图机制与处理技巧

Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效率也确实有点低了,自己还要加把劲,争取四月底全部看完,第六章讲的是Android的绘图机制,应该算是比较核心的东西了,不管什么功能,最终都是以图形的方式呈现给用户的,因此,掌握Android的绘图技巧,可以在让你设计应用的时候更加的随心所欲,对Android的理解更高 基本的绘图方法,相信读者都已经

第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁

原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测和处理这类问题. 死锁是当两个或者以上的事务互相阻塞引起的.在这种情况下两个事务会无限期地等待对方释放资源以便操作.下面是死锁的示意图: 本文将使用SQLServer Profiler来跟踪死锁.   准备工作: 为了侦测死锁,我们需要先模拟死锁.本例将使用两个不同的会话创建两个事务.   步骤:

&amp;gt;第六章 控制语句(rainbow 翻译)(来自重粒子空间)

控制|语句 <<展现C#>>第六章 控制语句(rainbow 翻译)  出处:http://www.informit.com/matter/ser0000002 正文:                                  第六章   控制语句     有一种语句,你在每种编程语言控制流程语句中都可以找到.在这一章中,我介绍了C#的控制语句,它们分为两个主要部分:.选择语句.循环语句如果你是C或C++程序员,很多信息会让你感到似曾相似:但是,你必须知道它们还存在着一些差

《.net编程先锋C#》第六章 控制语句(转)

编程|控制|语句 第六章 控制语句 有一种语句,你在每种编程语言控制流程语句中都可以找到.在这一章中,我介绍了C#的控制语句,它们分为两个主要部分:.选择语句.循环语句如果你是C或C++程序员,很多信息会让你感到似曾相似:但是,你必须知道它们还存在着一些差别. 6.1 选择语句当运用选择语句时,你定义了一个控制语句,它的值控制了哪个语句被执行.在C#中用到两个选择语句:.if 语句.switch 语句 6.1.1 if 语句最先且最常用到的语句是 if 语句.内含语句是否被执行取决于布尔表达式:

3D编程:第六章 Lighting Models

第六章 Lighting Models 在现实世界中,没有光照是无法看见东西的:一个物体能被看见,要么是通过反射光源,要么是自身发光.在使用计算机渲染时,模拟光线的交互可以使3D objects更逼真.但是光照的交互是一个非常复杂的过程,不能简单的在各种交叉的帧率之间进行复制(至少目前阶段还不行).因此,使用光照与3D objects交互的近似值或光照模型,在场景中实现更多的细节.本章主要介绍一些基础的光照模型. Ambient Lighting(环境光) 在一个光照环境中,环境光看起来远处不在

一篇文章彻底搞懂Android事件分发机制

本文讲的是一篇文章彻底搞懂Android事件分发机制,在android开发中会经常遇到滑动冲突(比如ScrollView或是SliddingMenu与ListView的嵌套)的问题,需要我们深入的了解android事件响应机制才能解决,事件响应机制已经是android开发者必不可少的知识.面试找工作的时候也是面试官经常会问的一个问题. 涉及到事件响应的常用方法构成 用户在手指与屏幕接触过程中通过MotionEvent对象产生一系列事件,它有四种状态: MotionEvent.ACTION_DOW

magento 开发 -- 深入理解Magento第六章 – 高级Magento模型

  第六章 – 高级Magento模型 我们讲过Magento有两种模型,简单模型和EAV(Entity Attribute Value)模型.上一章我们讲过所有的Magento模型都是继承自Mage_Core_Model_Abstract / Varien_Object.简单模型和EAV模型的区别在于资源模型(Model Resource).虽然所有的资源模型都最终继承"Mage_Core_Model_Resrouce_Abstract",但是简单模型是直接继承"Mage_

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

原文:ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性                                         深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第三篇 ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件 ASP.NET自定义控件组件开发 第三章 为控件添加事件 前