天天看點

JavaWeb-Servlet(四)ServletContextServletContext

接上篇:JavaWeb-Servlet(三)Servlet的一些細節

在正文之前,補充一點。

  • Servlet與反射

    當用戶端發送請求,伺服器接收到請求,根據web.xml中的資訊得到要響應的servlet類,這時得到的是一個類名的字元串,是以要利用反射來完成後續的工作。

ServletContext

1. ServletContext概述

伺服器會為每個應用建立一個ServletContext 對象::

  • ServletContext 對象的建立是在伺服器啟動時完成的;
  • ServletContext 對象的銷毀是在伺服器關閉時完成的。

一個項目隻有一個ServletContext對象!

ServletContext對象的作用是在整個Web應用的動态資源之間共享資料!例如在AServlet 中向ServletContext對象中儲存一個值, 然後在BServlet中就可以擷取這個值,這就是共享資料了。

2.擷取ServletContext

在Servlet中擷取ServletContext 對象:

  • 在void init(ServletConfig config)中:

    ServletContext context =config.getServletContext()

    ,
  • ServletConfig類的

    getServletContext()

    方法可以用來擷取ServletContext 對象。

在GenericServlet或HttpServlet中擷取ServletContext對象:

  • GenericServlet類有

    getServletContext()

    方法 ,是以可以直接使用

    this.getServletContext()

    來擷取。

3.域對象的功能

ServletContext是JavaWeb四大域對象之一。

  • PageContext;
  • ServletRequest;
  • HttpSession;
  • ServletContext;

所有域對象都有存取資料的功能,因為域對象内部有一個Map,用來存儲資料,下面是ServletContext對象用來操作資料的方法:

  • void setAttribute(String name, Object value)

    :用來存儲一個對象,也可以稱之為存儲一個域屬性,例如:

    servletContetxtAttribute("xxx", “XXX")

    ,在ServletContext中儲存了一個域屬性,域屬性名稱為xxx,域屬性的值為XXX。請注意,如果多次調用該方法,并且使用相同的name,那麼會覆寫上一次的值,這一特性與Map相同。
  • Object gettribute(String name)

    :用來擷取ServletContext中的資料,目前在擷取之前需要先去存儲才行,例如:

    String value = (String)servletContextAttribute("xxx");

    ,擷取名為xxx的域屬性;
  • void removeAttribute(String name)

    :用來移除ServletContext中的域屬性,如果參數name指定的域屬性不存在,那麼本方法什麼都不做;
  • Enumeration getAttributeNames()

    :擷取所有域屬性的名稱。

4.擷取應用初始化參數

Servlet也可以擷取初始化參數,但它是局部的參數;也就是說,一個servlet隻能擷取自己的初始化參數,不能擷取别人的,即初始化參數隻為一個Servlet準備。

還可以使用ServletContext來擷取在web.xml檔案中配置的應用初始化參數,即配置公共的初始化參數,為所有Servlet而用。

配置格式

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	......
	
	<context-param>
		<param-name>name1</param-name>
		<param-value>value1</param-value>
	</context-param>

	<context-param>
		<param-name>name2</param-name>
		<param-value>value2</param-value>
	</context-param>
	
	......
	
</web-app>

           

示例

public class AServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		/*
		 * 1.得到ServletContext 
		 * 2.調用它的getInitParameter(String name)方法得到初始化參數
		 */

		ServletContext context = this.getServletContext();
		String initParameter = context.getInitParameter("name1");
		System.out.println(initParameter);
	}
}
           

5.擷取資源的相關方法

JavaWeb-Servlet(四)ServletContextServletContext

1) 擷取真實路徑

還可以使用ServletContext對象來擷取Web應用下的資源,例如在應用的根目錄下建立a.txt檔案,現在想在Servlet中擷取這個資源,就可以使用ServletContext來擷取。

  • 擷取a.txt的真實路徑:

    String realPath = servletContext.getRealPath("/a.txt");

    , realPath的值為a.txt檔案的絕對路徑: F:\tomcat7\webapps\hello\a.txt
  • 擷取b.txt的真實路徑:

    String realPath= servletContext.getRealPath("/WEB-INF/b.txt");

2) 擷取資源流

不隻可以擷取資源的路徑,還可以通過ServletContext擷取資源流,即把資源以輸入流的方式擷取:

  • 擷取a.txt資源流:

    InputStream in= servletContext.getResourceAsStream("a.txt");

  • 擷取b.txt資源流:

    InputStream in= servletContext.getResourceAsStream("/WEB-INF/b.txt");

3) 擷取指定目錄下所有資源路徑

還可以使用ServletContext 擷取指定目錄下所有資源路徑,例如擷取/WEB-INF下所有資源的路徑:

ServletContext context = this.getServletContext();
Set set = context.getResourcePaths("/WEB-INF");
System.out.println(set);
           

注意!這個方法必須以“/”開頭!

輸出:

JavaWeb-Servlet(四)ServletContextServletContext

6.案例:通路量統計

一個項目中所有的資源通路都要對通路量進行了累加!

建立一個int類型的變量,用來儲存通路量,然後儲存到ServletContext的域中,這樣可以讓所有的Servlet都可以通路到。

  • 最初,ServletContext中沒有通路量相關的屬性,
  • 當本站第一次被通路的時候,建立一個變量,設定其值為1,儲存到ServletContext中;
  • 當以後的通路時,就可以從ServletContext中擷取這個變量,然後在其基礎之上加1。
public class AServlet extends HttpServlet {

	/**
	 * 統計網站通路量
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 擷取ServletContext對象
		ServletContext servletContext = this.getServletContext();

		// 從ServletContext對象中擷取名為count的屬性
		Integer count = (Integer) servletContext.getAttribute("count");

		// 如果存在,給通路量加1,然後儲存回去
		// 如果不存在,說明是第一次通路。向ServletContext中儲存名為count的屬性,值為1
		if (count == null) {
			servletContext.setAttribute("count", 1);
		} else {
			servletContext.setAttribute("count", count + 1);
		}

		// 向浏覽器輸出:需要使用響應對象
		PrintWriter pw = response.getWriter();
		pw.print("<h1>" + servletContext.getAttribute("count") + "</h1>");

	}
}
           

不過伺服器重新開機的話,計數就會被重置。