一、问题:
Request解决了一次请求内的数据共享问题,session解决了用户不同请求的数据共享问题,那么不同的用户的数据共享该怎么办呢?
解决:
使用ServletContext对象
二、作用:
解决了不同用户的数据共享问题
三、原理:
ServletContext对象由服务器进行创建,一个项目只有一个对象。不管在项目的任意位置进行获取得到的都是同一个对象,那么不同用户发起的请求获取到的也就是同一个对象了,该对象由用户共同拥有。
四、特点:
- 服务器进行创建
- 用户共享
- 一个项目只有一个
五、生命周期:
服务器启动到服务器关闭
六、作用域:
项目内
七、使用:
7.1获取ServletContext对象
(1)创建ServletContext对象(三种方式)
ServletContext sc1 = this.getServletContext(); ServletContext sc2 =this.getServletConfig().getServletContext(); ServletContext sc3=req.getSession().getServletContext();
7.2使用作用域进行共享数据流转
存储用户共享数据
sc.setAttribute(String name,Object value);
获取用户共享数据
sc.getAttribute(String name);
删除共享数据
sc.removeAttribute(String name);
7.3获取web.xml中的全局配置属性,作用:将部分动作和源文件进行解耦,我们只需要在xml配置文件中进行相关配置就会改变代码的执行效果。
<!-- 配置全局配置属性 --> <context-param> <param-name>flag</param-name> <param-value>true</param-value> </context-param>
sc.getInitParameter("flag");注意返回的是String类型数据
7.4获取webroot下项目资源流对象
sc.getResourceAsStream(String path);
注意:
path为相对路径,写从webRoot开始查找资源的路径即可。
7.5获取webroot下资源绝对路径
sc.getRealPath(String path);
注意:
path为相对路径,写从webRoot开始查找资源的路径即可。
八、案例:网页浏览次数统计
1//获取ServletContext对象 2 ServletContext sc=this.getServletContext(); 3 //获取计数器 4 Object obj=sc.getAttribute("nums"); 5 //判断 6 if(obj!=null){ 7 //计数器数据自增 8 int nums=(int) obj; 9 nums=nums+1; 10 //存储计数器数据到ServletContext对象 11 sc.setAttribute("nums", nums); 12 }else{ 13 sc.setAttribute("nums",1); 14 }
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.io.OutputStream; 9 import java.io.OutputStreamWriter; 10 11 import javax.servlet.ServletContext; 12 import javax.servlet.ServletException; 13 import javax.servlet.http.HttpServlet; 14 /** 15 * 1、在服务器关闭的时候将ServletContext中的计数器数据存储到nums.txt中 16 * 2、在服务器启动的时候将nums.txt中的数据存储到ServletContext中 17 * 18 * 19 * 20 * 21 * @author 22 * 23 */ 24 public class NumServlet extends HttpServlet { 25 //在服务器启动的时候将nums.txt中的数据存储到ServletContext中 26 @Override 27 public void init() throws ServletException { 28 //获取ServletContext对象 29 ServletContext sc=this.getServletContext(); 30 //获取nums.txt中存储的浏览器次数 31 //获取nums.txt的绝对路径(动态获取) 32 String path=sc.getRealPath("num/nums.txt"); 33 //创建File对象 34 File f=new File(path); 35 //读取nums.txt中的数据 36 //获取资源流对象 37 BufferedReader br=null; 38 InputStreamReader is=null; 39 FileInputStream fs=null; 40 try { 41 fs=new FileInputStream(f); 42 is=new InputStreamReader(fs); 43 br=new BufferedReader(is); 44 //读取 45 String nums=br.readLine(); 46 //将数据存储到ServletContext中 47 sc.setAttribute("nums",Integer.parseInt(nums)); 48 49 } catch (Exception e) { 50 e.printStackTrace(); 51 }finally{ 52 //关闭流资源 53 try { 54 fs.close(); 55 } catch (IOException e) { 56 // TODO Auto-generated catch block 57 e.printStackTrace(); 58 } 59 try { 60 is.close(); 61 } catch (IOException e) { 62 // TODO Auto-generated catch block 63 e.printStackTrace(); 64 } 65 try { 66 br.close(); 67 } catch (IOException e) { 68 // TODO Auto-generated catch block 69 e.printStackTrace(); 70 } 71 } 72 } 73 //在服务器关闭的时候将ServletContext中的计数器数据存储到nums.txt中 74 @Override 75 public void destroy() { 76 //获取ServletContext对象 77 ServletContext sc=this.getServletContext(); 78 //获取计数器数据 79 int nums=(int) sc.getAttribute("nums"); 80 //将计数器数据存储到nums.txt文件中 81 //获取nums.txt文件的绝对路径(动态获取) 82 String path=sc.getRealPath("num/nums.txt"); 83 //获取nums.txt的File对象 84 File f=new File(path); 85 //获取资源的流对象 86 BufferedWriter bw=null; 87 OutputStreamWriter ow=null; 88 FileOutputStream fs=null; 89 try { 90 //获取nums.txt的流对象 91 fs=new FileOutputStream(f); 92 ow=new OutputStreamWriter(fs); 93 bw=new BufferedWriter(ow); 94 //将数据写入到nums.txt中 95 bw.write(nums+""); 96 //刷新 97 bw.flush(); 98 } catch (Exception e) { 99 e.printStackTrace(); 100 }finally{ 101 //关闭流资源 102 try { 103 fs.close(); 104 } catch (IOException e) { 105 // TODO Auto-generated catch block 106 e.printStackTrace(); 107 } 108 try { 109 ow.close(); 110 } catch (IOException e) { 111 // TODO Auto-generated catch block 112 e.printStackTrace(); 113 } 114 try { 115 bw.close(); 116 } catch (IOException e) { 117 // TODO Auto-generated catch block 118 e.printStackTrace(); 119 } 120 } 121 } 122 }
<servlet> <servlet-name>NumServlet</servlet-name> <servlet-class>com.servlet.NumServlet</servlet-class> <load-on-startup>1</load-on-startup><!-- 配置Servlet服务器启动加载 --> </servlet>