当前位置: 首页 > news >正文

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

转载于:https://www.cnblogs.com/hellokitty1/p/4923088.html

相关文章:

  • JavaScript HTML DOM 事件
  • 3D-HEVC的TAppDecorder
  • Hibenate second-level ehcache
  • JVM垃圾回收日志结构分析
  • MFC用户界面套包BCGControlBar Pro for MFC v24.3正式发布[附下载]
  • 线程的创建
  • Android EditText 多行,滚动条 等
  • C#中两个时间的比较
  • Eclipse导入第三方库或工程时出现红色叹号的解决方法
  • Redis Ltrim 命令
  • android Volley 使用
  • glob 模块
  • 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
  • centos平台openstack spice配置
  • 专业级的PHP IDE——Zend Studio正式发布v13[附下载]
  • Angular 响应式表单 基础例子
  • Asm.js的简单介绍
  • Computed property XXX was assigned to but it has no setter
  • express + mock 让前后台并行开发
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • php ci框架整合银盛支付
  • Phpstorm怎样批量删除空行?
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • spark本地环境的搭建到运行第一个spark程序
  • Vue.js-Day01
  • vue2.0项目引入element-ui
  • Yeoman_Bower_Grunt
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 利用DataURL技术在网页上显示图片
  • 聊聊redis的数据结构的应用
  • 码农张的Bug人生 - 初来乍到
  • 少走弯路,给Java 1~5 年程序员的建议
  • 小程序开发之路(一)
  • 移动端 h5开发相关内容总结(三)
  • ​MySQL主从复制一致性检测
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (12)Linux 常见的三种进程状态
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (九)信息融合方式简介
  • (南京观海微电子)——COF介绍
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (轉)JSON.stringify 语法实例讲解
  • .gitattributes 文件
  • .gitignore文件设置了忽略但不生效
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 使用 XPath 来读写 XML 文件
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET/C# 使窗口永不获得焦点
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)