目錄
ServletContext對象用於獲取上下文路徑(所謂的上下文路徑,其實就是項目名稱)
1、Tomcat簡介
因爲Servlet是在容器中運行的,這裏用的容器是Tomcat。Tomcat 是由 Apache 開發的一個 Servlet 容器,實現了對 Servlet 和 JSP 的支持。Tomcat 本身也內含了一個 HTTP 服務器,它也可以被視作一個單獨的 Web 服務器,但是注意,但是,不能將 Tomcat 和 Apache HTTP 服務器混淆。
2、Servlet的生命週期簡介
- Servlet對象的創建
- 由Tomcat去new一個Servlet對象
- init() Servlet的初始化
- init 方法只會在第一次創建的時候被調用一次,在後續的過程中不會再被調用;
- service() Servlet的服務方法,用來處理客戶端請求
- service方法是執行實際任務的主要方法。Servlet容器調用service方法來處理來自客戶端的請求,並把格式化的響應寫會給客戶端;
- 每一次服務器收到一個來自客戶端的請求,服務器就會產生一個新的線程並調用服務;
- service方法會檢查HTTP請求類型(get、post、put、delete...等),並在適當的時候調用 doGet() / doPost() / doPut() / doDelete()...等方法;
- destory() Servlet的終止、結束方法
- destory也只會被調用一次,在Servlet生命週期結束的時候被調用 ;
- destory 方法可以讓你的Servlet關閉數據庫連接,停止後臺線程等執行相應的清理活動。
- 最後,由JVM進行垃圾回收
3、用代碼模擬聲明週期的全過程
public class LifeCycle extends HttpServlet {
// 自己寫的無參構造,用來模擬對象創建
public LifeCycle ()
{
System.out.println("servlet 對象被創建...");
}
//覆寫init方法,模擬初始化
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("servlet 被初始化...");
}
// 覆寫服務方法,模擬處理客戶端請求
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet 服務方法被調用...");
}
// 覆寫銷燬方法,模擬銷燬servlet方法
@Override
public void destroy() {
System.out.println("Servlet 被銷燬...");
}
}
然後打開三個網頁發起請求,如圖:
然後運行結果:
從運行結果中也能看出來,當有多個客戶端請求服務器時,servlet對象只會創建一次,初始化一次,然後每來一個請求就創建一個線程調用一次服務方法處理請求。如下圖所示:
4、ServletConfig對象
在上面覆寫init方法的時候,覆寫的是 init( ServletConfig config) ,有一個參數,其實在源碼中(GenericServlet 這個類裏面),還有一個init方法,是沒有參數的。
兩個方法如下:
// 這一個方法有一個參數,是用於獲取配置信息的時候用的,servlet生命週期的初始化就使用的這個方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
// 這個方法是Servlet初始化的簡便方法,比如 用戶自定義參數的時候使就可以使用這個方法
public void init() throws ServletException {
}
那麼怎麼獲取那個config對象呢???
初始化參數:當Servlet容器初始化Servlet時,Servlet容器會給Servlet的init方法傳入一個ServletConfig。ServletConfig封裝可以通過部署描述符傳給Servlet的配置信息。這樣傳入的一條信息就叫初始化參數,一個初始化參數由key 和 value組成。
獲取初始化參數:爲了從Servlet內部獲取到初始化參數的值,要找Servlet容器傳給Servlet的init方法的ServletConfig中調用getInitParameter方法獲取。
舉個例子:
運行結果:
可是這麼弄有什麼用呢???
比如:現在有一個需求,要讀取 aaa.txt 的文件內容,等你剛寫完,需求又變爲讀取bbb.txt的文件內容......在實際工作中一般不會頻繁的改變源碼,所以這個時候我們就要讀取的文件放在web.xml中。配置如下:
案例:讀取文件內容:
public class ReadFileServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 獲取config對象
ServletConfig config = this.getServletConfig();
// 獲取路徑
String path = config.getInitParameter("path");
// 按行讀取文件
String str ;
BufferedReader br = new BufferedReader(new FileReader(path));
while ((str=br.readLine()) != null)
{
System.out.println(str);
}
}
}
5、ServletContext對象
ServletContext對象用於獲取上下文路徑(所謂的上下文路徑,其實就是項目名稱)
案例:獲取上下文路徑
public class ContextDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 獲取ServletContext對象
ServletContext context = this.getServletContext();
System.out.println(context.getContextPath());
}
}
運行結果: