作用域对象 | 属性操作方法 | 作用域范围说明 |
ServletContext(上下文) | void setAttribute(String, Object) Object getAttribute(Sting) void removeAttribute(String) Enumeration getAttributeNames() | 整个Web应用程序 |
HttpSession(会话) | 一个会话交互过程 | |
ServletRequest(请求) | 一次请求过程 |
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
![](https://i-blog.csdnimg.cn/blog_migrate/382557184262c8e2e6bb28fca758b9c9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/62cdd007b9530b2b00fada4012509a89.png)
事件类型 | 描述 | Listener接口 | |
ServletContext 事件 | 生命周期 | Servlet上下文刚被创建并可以开始为第一次请求服务,或者Servlet上下文将要被关闭发生的事件 | ServletContextListener |
属性改变 | Servlet上下文内的属性被增加、删除或者替换时发生的事件 | ServletContextAttributeListener | |
HttpSession 事件 | 生命周期 | HttpSession被创建、无效或超时时发生 | HttpSessionListener HttpSessionActivationListener |
会话迁移 | HttpSession被激活或钝化时发生 | ||
属性改变 | 在HttpSession中的属性被增加、删除、替换时发生 | HttpSessionAttributeListener HttpSessionBindingListener | |
对象绑定 | 对象被绑定到或者移出HttpSession时发生。 | ||
ServletRequest 事件 | 生命周期 | 在Servletr请求开始被Web组件处理时发生 | ServletRequestListener |
属性改变 | 在ServletRequest对象中的属性被增加、删除、替换时发生 | ServletRequestAttributeListener |
三:监听Web应用程序范围内的事件
监听器需要在web.xml定义监听器:
<listener>
<listener-class>com.cy.listener.servletContext</listener-class>
</listener>
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
HttpSessionBindingEvent类提供如下方法:
public String getName():返回绑定到Session中或从Session中删除的属性名字。
public Object getValue():返回被添加、删除、替换的属性值
public HttpSession getSession():返回HttpSession对象
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 }
五:监听请求生命周期内事件