1. 程式人生 > >(轉)JavaWeb學習之Servlet(二)----Servlet的生命周期、繼承結構、修改Servlet模板

(轉)JavaWeb學習之Servlet(二)----Servlet的生命周期、繼承結構、修改Servlet模板

ext 核心 system 網頁 基本 麻煩 extends 用戶名 servlet對象

【聲明】

歡迎轉載,但請保留文章原始出處→_→

文章來源:http://www.cnblogs.com/smyhvae/p/4140466.html

一、http協議回顧:

在上一篇文章中:JavaWeb學習之Servlet(一)----MyEclipse及Tomcat的配置,我們通過在瀏覽器輸入url,就能看到在MyEclipse中編寫的Servlet資源,效果如下:

技術分享

上圖中,整個過程是這樣的:瀏覽器中輸入url後,會通過hosts文件/dns服務器解析為IP地址,進而找到對應ip地址的服務器。

在這期間,瀏覽器會通過http協議發出請求。服務器端收到請求後,做了下面這些事:

(1)分析出當前請求的是哪臺虛擬主機:

  • 查看Host請求頭分析出訪問的是哪臺虛擬主機
  • 如果沒有Host請求頭(在瀏覽器地址欄直接輸入ip地址而不是url),則訪問缺省虛擬主機

(2)分析當前請求訪問的是當前虛擬主機的哪個Web應用:

  • 從請求行中請求的資源部分來分析

(3)分析當前請求要訪問的是這個Web應用的哪個資源:

  • 從請求行的資源部分分析出訪問的是哪個資源

(4)查找web.xml文件,查看有沒有對應的虛擬路徑,如果有則用這個虛擬路徑對應的資源做響應

技術分享

(5)服務器從response對象中獲取之前寫入的數據(這就是寫在Servlet當中的java代碼),組織成http響應消息發給瀏覽器

註:第(5)句話便是本文要學習的重點。

二、Servet的運行過程及生命周期

Servlet程序是由WEB服務器調用,web服務器收到客戶端的ServletWeb服務器首先檢查是否已經裝載並創建了該Servlet的實例對象。如果是,則直接執行第(4)步,否則,執行第(2)步。

訪問請求後:

(1)裝載並創建該Servlet的一個實例對象。

(2)調用Servlet實例對象的init()方法。

(3)創建一個用於封裝HTTP請求消息的HttpServletRequest對象和一個代表HTTP響應消息的HttpServletResponse對象,然後調用Servlet的service()方法並將請求和響應對象作為參數傳遞進去。

(4)WEB應用程序被停止或重新啟動之前,Servlet引擎將卸載Servlet,並在卸載之前調用Servlet的destroy()方法。

Servet的生命周期:

Servlet 的生命周期定義了一個Servlet如何被加載、初始化,以及它怎樣接收請求、響應請求、提供服務。

生命周期如下:

  • (1)通常情況下,服務器會在Servlet第一次被調用時創建該Servlet類的實例對象(servlet出生),創建出對象後立即調用init()方法做初始化操作;
  • (2)一旦被創建出來,該Servlet實例就會駐留在內存中,為後續對這個Servlet的請求做服務,每次對這個Servlet的訪問都會導致Servlet中Service方法執行;
  • (3)當web應用被移除容器或者關閉服務器時,隨著web應用的銷毀,Servlet也會被銷毀(servlet死亡)。在銷毀之前服務器會調用Servlet的destroy方法做一些善後的工作。

有3個方法代表了Servlet的生命周期:

  • init方法,負責初始化Servlet對象。
  • service方法,負責響應客戶的請求(調用doGet或doPost等方法)。
  • destroy方法,當Servlet對象退出生命周期時,負責釋放占用的資源。

註:在Servlet的整個生命周期內,Servlet的init方法只有在servlet被創建時被調用一次,每次對這個Servlet的訪問都會導致Servlet中Service方法執行。

例如:現在瀏覽器連續訪問Servlet 10次,內存中只有一個Sevlet對象。Servlet對象由服務器創建(創建一次),request和response由Servlet容器創建(創建10次)

來看一段代碼:

技術分享
 1 package com.vae.servlet;
 2 import java.io.IOException;
 3 import java.io.PrintWriter;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 //一般實現一個Servlet,只要繼承HttpServlet類即可
 9 public class MyServlet extends HttpServlet {
10     //Servlet初始化時調用的方法
11     @Override
12     public void init() throws ServletException {
13         super.init();
14         System.out.println("init....");
15     }
16     
17     //Servlet被銷毀時調用的方法
18     @Override
19     public void destroy() {
20         super.destroy();
21         System.out.println("destroy...");
22     }
23     //-------doGet/doPost 核心的業務處理方法(由service方法來調用)------------    
24     @Override
25     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
26             throws ServletException, IOException {
27         //super.doGet(req, resp);
28         doPost(req, resp);
29         System.out.println("do service...");
30     }
31     
32     @Override
33     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
34             throws ServletException, IOException {
35         //super.doPost(req, resp);
36     }
37 }
技術分享

運行程序,輸入url,此時,一按回車,馬上就會在後臺打出日誌:

技術分享

然後連續刷新三次網頁,日誌如下:

技術分享

可以看到,Servelet只會初始化一次,之後的話,我們多次訪問的是同一個Sevlet對象。此時,即使關掉網頁,Servlet也不會銷毀,只有關掉Tomcat服務器才會銷毀Servlet。

需要註意的是,前臺可能有get和post兩種請求,但是在後臺做的處理是一樣的。例如:前臺輸入用戶名密碼,在後臺驗證的時候是不區分哪一種請求方式的。於是,如果在doGet()方法中寫了代碼內容,我們可以在doPost()方法中加一句:"doGet(req,resp);"即可,就可以進行重復利用(畢竟執行的都是同一段邏輯)。

三、Servlet的繼承結構:

  • Servlet接口:定義了Servlet應該具有的基本方法
  • GenericServlet:抽象類,實現了Servlet接口。通用基本Servlet實現,對於不常用的方法在這個實現類中進行了基本的實現,將Service設計為了抽象方法,需要子類去實現
  • HttpServlet:抽象類,繼承了GenericServlet類。在通用Servlet的基礎上基於HTTP協議進行了進一步的強化:復寫了GenericServlet中的Service方法,Service方法體內的代碼會自動判斷用戶的請求方式,如為GET請求,則調用HttpServlet的doGet方法,如為Post請求,則調用doPost方法。因此,開發人員在編寫Servlet時,通常只需要繼承HttpServlet,然後覆寫doGet或doPost方法,而不要去覆寫service方法。

四、修改Servlet模板:

使用MyEclipse創建Servlet時,根據默認的Servlet模板生成的Servlet代碼如下:

技術分享 View Code

在實際開發中,這些生成的代碼和註釋一般我們都用不到的,每次都要手工刪除這些註釋和代碼,很麻煩,因此可以根據開發的實際情況修改Servlet的模板代碼,改成符合實際開發需求的模板代碼。

MyEclipse 10修改Servlet模板的步驟如下:

關閉MyEclipse,找到MyEclipse安裝目錄下的\Common\plugins文件夾,比如:D:\MyEclipse10\Common\plugins,然後找到com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar這個jar文件,如下圖所示:

技術分享

用壓縮工具打開,註意是打開而不是解壓這個jar包,如下圖所示:

技術分享

技術分享

上圖中,打開Jar包中的Templates文件夾中的Servlet.java文件,可以看到裏面的模板代碼:

技術分享 View Code

代碼模板中,刪除doGet和doPost上方的註釋和方法裏面的代碼,並在doPost方法裏面添加一行doGet(request,response);效果如下:

技術分享

修改好之後,保存,重啟MyEclipse,就可以使用新的模板代碼了:

技術分享
package com.vae.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Servlet2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
技術分享

(轉)JavaWeb學習之Servlet(二)----Servlet的生命周期、繼承結構、修改Servlet模板