天天看點

JSP學習之ServletContext對象

ServletContext對象

  • 問題:

    Request解決了一次請求内的資料共享問題,session解決了使用者不同請求的資料共享問題,那麼不同的使用者的資料共享該怎麼辦呢?

  • 解決:

    使用ServletContext對象

  • 作用:

    解決了不同使用者的資料共享問題(如目前網頁被浏覽的次數)

  • 原理:

    ServletContext對象由伺服器進行建立,一個項目隻有一個對象。不管在項目的任意位置進行擷取得到的都是同一個對象,那麼不同使用者發起的請求擷取到的也就是同一個對象了,該對象由使用者共同擁有。

  • 特點:

    伺服器進行建立

    使用者共享

    一個項目隻有一個

  • 生命周期:

    伺服器啟動到伺服器關閉

  • 作用域:

    項目内

  • 使用:

    (1)擷取ServletContext對象:三種方式

方式一:(常用)
ServletContext sc = this.getServletContext();
           
方式二:
ServletContext sc2 = this.getServletConfig().getServletContext();
           
方式三:(常用)
 ServletContext sc3 = req.getSession().getServletContext();
           

(2)使用ServletContext對象完成資料共享: 使用作用域進行共享資料流轉

資料存儲:sc.setAttribute(name, value)
           
資料擷取:sc.getAttribute(name)傳回的Object類型
           
注意:
	不同的使用者可以給ServletContext對象進行資料的存取。
	擷取的資料不存在傳回null。
           

(3)擷取web.xml中的全局配置

Web.xml:(配置全局資料):
<context-param>(一個該标簽隻能有一組鍵值對,多個聲明多個該标簽)
		<param-name>name</param-name>
		<param-value>zhangsan</param-value>
</context-param>

//擷取web.xml全局配置
String names = Sc.getInitParameterNames();//傳回鍵名的枚舉類
String name = Sc.getInitParameter(“name”);//擷取上面全局配置參數, 資料不存在傳回null

作用:将靜态資料和代碼進行解耦;(相當于異地戀)。
           

(4)擷取MyEcplise中webroot(Eclipse中的webContent檔案夾)下資源絕對路徑

擷取項目根目錄下的資源的絕對路徑:
	IO流寫法,固定寫好的:
	String path = “D:\\tomcat\webapps\sc\doc\1.txt”; 
	
動态擷取:擷取的目錄是項目根目錄,path參數為項目根目錄中的路徑
      String path = sc.getRealPath(String path);
           

(5)擷取webContent或webroot項目根目錄下資源的流對象

InputStream is = Sc.getResoureAsStream(String path);

注意:
	此種方式隻能擷取項目根目錄下的資源流對象,可以取到和WEB-INF統計目錄下的檔案的流對象;
	class檔案的流對象需要使用類加載器擷取(不進WEB-INF檔案夾);
	編譯好的class檔案不能取到;
           

案例(ServletContext對象網站計數器)

  • 原理:在使用者登入校驗中建立計數器并自增,然後存儲到ServletContext對象中,在首頁面裡取出計數器資料顯示給使用者即可。
  • 實作:

    第一步:在登入成功的servlet進行重定向之前,建立計數器或計數器加1。

//建立網頁計數器:
	//擷取計數資料
	ServletContext sc = this.getServletContext();
	if( sc.getAttribute(“nums”) != null){
		int nums = (int)sc.getAttribute(“nums”);
		//計數器自增
		nums+=1;
		//再次存儲到ServletContext對象中
		sc.setAttribute(“nums”, nums);
	}else{
		sc.setAttribute(“nums”, 1);
	}
           

第二步:在登入成功後繪制頁面的servlet中擷取網頁浏覽次數并顯示

//擷取網頁浏覽次數
int nums = Integer.parseInt(this.getServletContext().getAttribute(“nums”))
response.getWriter().write(“目前網頁浏覽次數為:”+nums)
           

第三步:在cookie登入校驗三天免登陸的重定向之前網頁計數器也要自增,因為也是一次登入。

int nums = (int)sc.getAttribute(“nums”);
	//計數器自增
	nums+=1;
	//再次存儲到ServletContext對象中
	sc.setAttribute(“nums”, nums);
           
  • 問題:

    重新開機伺服器,計數器就會重置

  • 解決方法:

    在webroot(WebContent)下面建立nums檔案夾,建立nums.txt。在網站關閉時,将計數器資訊寫入nums.txt。

  • 解決實作:

    建立NumServlet,别名:/num

覆寫init初始化方法,将資料讀取到ServletContext對象中
init(){
	//擷取檔案中的計數器資料
	//擷取檔案路徑
    	  String path = this.getServletContext().getRealPath(“/num/nums.txt”);
	//聲明流對象
	FileReader fr=null;
	BufferedReader br = null;
	try{
   		fr= new FileReader(path);
   		br = new BufferedReader(fr);
   		String nums = br.readLine();//第一次啟動時為null,但在之前設定了為null判斷,是以不會出錯
		System.out.println(nums)
   		this. sc.getServletContext().setAttribute(“nums”,nums);
	} catch(Exception e){
      	e.printStackTrace();
	}finally{
    	  //下面關閉需要try
      	fr.close();
      	br.close();
	}
}
           
覆寫銷毀方法,存儲計數器到檔案中
Destroy(){
      //擷取網頁計數器
      String num = (String) this.getServletContext().getAttribute(“nums”);
      //聲明流對象
      BufferedWriter bw = null;
      FileWrier fw = null;
      //擷取檔案路徑
      String path = this.getServletContext().getRealPath(“/num/nums.txt”);
      try{
      	fw = new FileWriter(path);
      	bw = new BufferedWriter(fw);
      	bw.write(nums+“”);//将nums轉換為string類型
      	bw.flush();
	}catch(Exception e){
    	  e.printStackTrace();
	}finally{
	      //下面關閉需要try
      		fw.close();
    	  	bw.close();
}
           
打開web.xml檔案,找到NumServlet,配置<load-on-startup>1</load-on-startup>