Servlet基礎知識


web開發的背景知識(了解)


 

       (1)主機/終端

            特點:主機負責所有的業務運算和數據的管理,終端只提供操作界面。

優點:可靠

缺點:昂貴,維護困難

    (1)二層的c/s:

                  特點:使用數據庫當服務器(數據庫不僅要保存數據,還需要編寫大量的業務處理邏輯,客戶端

               負責界面及部分的業務處理邏輯)。

         優點:開發方便

                  缺點:可移值性差(比如,要換數據庫,就需要重新寫一次業務處理邏輯,因為數據庫的編程語

               言是不一樣的)。

               另外,要求客戶端跟數據庫之間保持一個數據庫連接,所以,不適合開發大型的應用(數

               據庫能夠提供的數據庫連接的個數是有限制的)。

         (2)三層的c/s: 客戶端/服務器端程序

                  特點:數據庫只負責管理數據,所有的業務邏輯寫在應用服務器里面,客戶端負責界面。

         優點:可移植性好,適合開發大型應用

                  缺點:客戶端需要單獨安裝,開發相對比較復雜(需要開發通訊處理模塊,需要自定義協議)。

         (3) b/s:

                  特點: 數據庫只負責管理數據,所有的業務邏輯寫在web服務器里面,客戶端使用標准的瀏覽器。

                   其實,b/s架構從本質上講,是一種標准化的c/s:即使用標准化的通訊協議(http協議),標

               准化的客戶端程序(瀏覽器),標准化的服務器(比如tomcat)。

                  優點:客戶端不再需要安裝,另外,開發相對簡化(通訊模塊不再需要開發了,也不再需要自定

               義協議)。

2、什么是Servlet?

sun公司制訂的一種用於擴展web服務器功能的組件規范。

    (1)擴展web服務器功能:

             1)早期的web服務器(比如,apache ws,iis)只能夠處理靜態資源(即需要事先將html文件寫好)的

            請求,不能夠處理動態資源(需要依據用戶的請求進行計算然后生成對應的html)的請求。

             2)早期,可以使用cgi程序來擴展web服務器: cgi程序可以使用很多語言來開發,比如perl,c

            等等都可以,但是,cgi程序有幾個問題(比如,開發復雜,可移植差,性能不是特別好,因

            為會啟動過多的cgi進程)。

             3)servlet也可以擴展web服務器(即動態生成頁面)功能:

                    方案一:瀏覽器發請求給web服務器(比如,apache ws,iis,這些web服務器本身是不能夠處理靜

                   態資源的請求的),web服務器判斷是否需要計算,如果需要,會調用servlet容器,servlet

                   容器再去調用servlet處理請求。

                    方案二 瀏覽器直接發請求給servlet容器(比如tomcat,jetty),因為servlet容器除了可以運行

                   servlet之外,同時,也可以充當簡單的web服務器。

   (2)組件規范

            1)組件:

                   符合一定規范,實現部分功能的,並且可以部署在相應的容器里面運行的程序模塊。

          servlet就是一個組件,我們在寫servlet時,不需要考慮網絡編程相關的問題,這些問題都由servlet

          容器(比如:tomcat)去解決。

            2)容器:

                   符合一定規范,為組件提供運行環境和相應的基礎服務(比如網絡服務)的程序。並且管理組件

          的生命周期程序。

                  servlet容器(比如,tomcat或者jboss)會提供servlet的運行環境。

3、如何開發一個servlet?

       step1、寫一個java類(servlet只能夠使用java語言來開發),該類需要實現Servlet接口或者繼承

           HttpServlet抽象類。

         step2、編譯

         step3、打包

                           appname(應用名)

                                    WEB-INF

                                             classes(.class文件)     

                                             lib(可選, .jar文件)

                                             web.xml(部署描述文件)

         step4、部署

                           將step3創建的整個文件夾拷貝到servlet容器特定的文件夾(webapps)下面。或者也可以

              將整個文件夾先使用jar命令壓縮成.war文件然后再拷貝。

         step5、訪問

                           啟動servlet容器(web服務器),在瀏覽器地址欄輸入http://ip:port/appname/servlet-url其中,

              servlet-url參見web.xml。

4、tomcat的安裝和簡單的使用

windows環境

step1、將tomcat解壓到D:/  路徑:D:\apache-tomcat-5.5.23

step2、配置環境變量

   (1)JAVA_HOME(JDK的主目錄) 必須配置

   (2)tomcat的主目錄              可以不配置

   (3)tomcat的bin目錄            可以不配置

            1)“我的電腦”右擊“屬性”,打開“系統屬性”的“高級”選項卡,找到“環境變量”

       2)新建系統變量,或用戶變量

          變量名為:JAVA_HOME  變量值為:JDK目錄

step3、啟動 tomcat服務器

       進入啟動tomcat的bin目錄下,雙擊“startup.bat”(windows系統)

       關閉tomcat服務器

  雙擊stutdown.sh

linux環境:

         step1、找到tomcat的壓縮文件(比如/opt/apache-tomcat5.5.23.tar.gz),然后解壓到/home/soft01。

           (也可以去www.apache.org去下載tomcat)

         step2、配置環境變量(大家現在可以不用配置)

                   cd /home/soft01

                   vi .bash_profile

                   在該文件當中,添加

                   JAVA_HOME: JDK的安裝路徑,比如/opt/java6.0

                   CATALINA_HOME: tomat的安裝路徑,比如 /home/soft01/apache-tomcat5.5.23

                   PATH:  /home/soft01/apache-tomcat5.5.23/bin

         step3、啟動tomcat

                           cd /home/soft01/apache-tomcat5.5.23/bin

                           sh startup.sh (或者 sh catalina.sh run)

                           接下來,打開瀏覽器,輸入:http://localhost:8080

         step4,關閉tomcat

                           cd /home/soft01/apache-tomcat5.5.23/bin

                           sh shutdown.sh

tomcat的幾個主要文件夾的作用

1)bin: 是一些可執行文件(比如,啟動和關閉tomcat)

2)common: 放置可以被部署到該服務器上面的所有的程序都可以訪問的jar文件。

3)conf:服務器的配置文件。

4)webapps:tomcat的部署文件夾。

5、Servlet是如何運行的?

比如,從瀏覽器地址欄輸入http://ip:port/firstweb/sayHello

(1) 瀏覽器依據ip,port建立與servlet容器之間的連接。

(2) 瀏覽器將請求資源路徑("/firstweb/sayHello")      及相關的參數打包(按照http協議)發送給容器。

(3) 容器拆包,解析請求數據包,將解析之后的結果數據存放到一個request對象里面,同時還會

      創建一個response對象。

(4) 容器依據請求資源路徑找到Servlet的配置,然后創建對應的Servlet對象(這兒,會創建

           HelloServlet對象)。

(5) 容器調用Servlet對象的service方法(會將step3創建好的request,response對象作為參數傳遞進

           來),可以在該方法里面,通過訪問request對象的相應方法來獲取參數值,也可以將處理結果寫

           到response對象里。正因為有這樣兩個對象,Servlet不用考慮網絡相關的問題(比如獲取請求

           參數,就不用拆包,同樣,將結果輸出給瀏覽器,也不需要打包)。

(6) servlet容器從response對象里面取出處理結果,然后打包,發送給瀏覽器。

(7) 瀏覽器拆包,解析響應數據包,取出數據,生成相應的界面。

6、使用eclipse開發Servlet程序

HelloServlet.java

public class HelloServlet extends HttpServlet{

/* 覆蓋(override)HttpServlet的service方法。

* 服務器在創建好servlet對象之后,會調用該方法來處理請求。

        */

public void service(HttpServletRequest request,

HttpServletResponse response) throws ServletException,IOException{

                 System.out.println("service方法正在執行...");

//1 讀取請求參數 String name = request.getParameter("name");

//2 處理請求 String rs = "<h1>" + "hello " + name + "</h1>";

//3 生成響應

        1)生成一個消息頭content-type,告訴 瀏覽器,返回的數據類型。

response.setContentType("text/html;charset=utf-8");

2)獲得一個輸出流

        PrintWriter out = response.getWriter();

        3)向流中輸出數據,其實質是,將處理結果存放 到response對象上。

        out.println(rs);

 4)關閉流*

out.close(); }

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"

xmlns="http://java.sun.com/xml/ns/j2ee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>

<servlet-name>helloServlet</servlet-name>

<!--servlet-class:一定要將類的完整的名稱寫出來 -->

<servlet-class>web.HelloServlet</servlet-class>

              </servlet>

              <servlet-mapping>

<servlet-name>helloServlet</servlet-name>

<url-pattern>/sayHello</url-pattern>

              </servlet-mapping>

</web-app>

7、常見錯誤及及解決方式

   (1)404

           a,錯誤的原因:請求資源路徑寫錯。

           b,解決方式:檢查請求資源路徑。 http://ip:port/appname/servlet-url

         (2)500

            a,錯誤的原因:系統出錯(程序出錯或者是程序所運行的環境,比如數據庫、網絡等出現問題)。

            b,解決方式: 檢查代碼(包括配置文件),檢查運行環境。

         (3)405

            a,錯誤的原因: 找不到service方法

            b,解決方式:檢查方法的簽名

8、http協議(了解)

(1)什么是http協議(超文本傳輸控制協議)?

   由w3c定義的一種應用層協議,用來定義瀏覽器與web服務器之間通訊的過程及數據的格式。

   1)、瀏覽器與服務器之間通訊的過程:

          step1、瀏覽器建立與服務器之間的連接

          step2、瀏覽器打包(按照http協議的要求),發送請求

          step3、服務器處理完請求,將數據打包,發送響應

          step4、服務器關閉連接

          特點: 一次請求,一次連接。

 優點:效率非常高,服務器可以盡可能的為更多的客戶端(瀏覽器)服務。

   2)、數據的格式

          a、請求數據包

             請求行

請求方式 請求資源路徑協議的類型和版本

             若干消息頭

消息頭是一些鍵值對,通信的雙方都可以發送。比如,瀏覽器可以發送user-agent消息頭告

訴服務器瀏覽器的類型和版本。

一般來說,一般由瀏覽器或者服務器自動生成,表示特定的含義。有些時候,需要編程生

成一些消息頭。

             實體內容

如果發送get請求,實體內容為空。

只有發送post請求時,實體內容才會有數據(即請求參數值,比如nam=tom),如果是get請

求,請求參數會添加到請求資源路徑的后面。

          b、響應數據包

             狀態行

協議的類型和版本 狀態碼 狀態描述

                       狀態碼是一個3位數字,由w3c定義的,表示服務器處理請求的一種狀態,比如:

                           404:依據請求資源路徑,找不到對應的資源

                           500:系統出錯

                           200:正常

             若干消息頭

比如,服務器可以向瀏覽器發送一個content-type的消息頭,告訴瀏覽器返回的數據類型以

及編碼格式。瀏覽器按照消息頭的內容打開返回的數據。

response.setContentType(“text/html”);  返回的是一個html頁面,編碼格式是ISO-8859-1

response.setContentType(“text/html;charset=utf8”);返回的是一個html頁面,編碼格式是utf-8

             實體內容

程序處理的結果  

9、get請求與post請求

       (1)哪一些情況下,瀏覽器發送get請求

                  a、直接在瀏覽器地址欄輸入某個地址

                  b、點擊鏈接

                  c、表單默認提交 

         (2)哪一些情況下,瀏覽器發送post請求

                  a、表單設置了method="post"。

         (3)get請求的特點

                  a、會將請求參數添加到請求資源路徑的后面,因為請求行最多只能存放大約2K左右的數據,所

            以適合提交少量的數據給服務器。優點就是提交小數據時方便

                  b、請求參數會顯示在瀏覽器地址欄,不安全(比如,路由器會記錄這個地址)。

         (4)post請求的特點

                  a、會將請求參數添加到實體內容里面,能夠提供大量的數據給服務器。

                  b、請求參數不會顯示在瀏覽器地址欄,相對安全。

   要注意的是post方式並不會對請求參數加密(這里不安全)。

   比如:姓名、密碼需要加密的,需要使用HTTPS協議。 (需要服務器端進行配置)

HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議要比http協議安全。

10、web編程中的編碼問題

         1)常識:

                  a、java語言會將所有字符以unicode編碼格式保存在內存里面。

                  b、編碼:將以unicode編碼格式對應的字節數組轉換成某種本地編碼格式(gbk,gb2312,utf-8)對應

                  的字節數組。    

              c、解碼:將某種本地編碼格式對應的字節數組轉換成unicode編碼格式對應的字節數組。   

//encode方法先進行編碼,然后將得到字節數組轉換成一個字符串。

                  String str = URLEncoder.encode("過兒","utf-8");  以utf-8格式編碼

                  System.out.println(str);

                  String str2 = URLDecoder.decode(str,"utf-8");   以utf-8格式解碼

                  System.out.println(str2);

             

         2)servlet如何輸出中文?

            (1)產生亂碼問題的原因?

                     a、out.println(中文):(編碼)

                     默認采用iso-8859-1編碼格式進行編碼,iso-8859-1,這個編碼是不支持中文的。

                     b、服務器默認情況下,會發送一個content-type消息頭,該消息頭指定的編碼是iso-8859-1,

               瀏覽器會使用該編碼格式打開頁面。(解碼)

       (2)解決方式

                     response.setContentType("text/html;charset=支持中文的某種編碼");

                     該方法有兩個作用:

                作用1:編碼

 out.println時,使用正確的編碼格式進行編碼(unicode -- >utf-8)。

                作用2:解碼

          生成一個消息頭content-type,該消息頭會指定一個編碼,讓瀏覽器以該編碼來打開頁面。

     

11、表單處理

         (1)如何獲得表單的參數值?

                  a、String request.getParameter(String paraName);

                     注意:

   1)如果paraName與實際傳遞的參數名稱不一致,會返回null。

                              2)在文本輸入框中,如果不輸入,會獲得空字符串"",需要注意對""的處理。

                  b、String[] request.getParameterValues(String paraName);

                     注意:如果有多個請求參數名稱相同,使用個方法。

                     比如: city=bj&city=wh&city=hz,應該request.getParameterValues("city");

   或者

                           <form action="/web01/first" method="post">

                                             interst:cooking<input type="checkbox" value="cooking" name="interst"/>

                                                       finshing<input type="checkbox" value="fishing" name="interst"/>

                                                      <input type="submit" value="提交"/>

                </form>

  服務器端:采用 request.getParameterValues("interstate");獲得用戶的選擇 

         (2)表單中如果有中文參數,如何處理?

                  a、亂碼問題產生的原因

                     瀏覽器會對表單中的中文參數按照打開該表單時編碼格式來編碼

            比如,瀏覽器按照utf-8打開頁面,則使用utf-8對該表單的中文參數進行編碼。服務器端,

            默認使用iso-8859-1去解碼。

                  b、解決方式:

                           step1 在html文件當中,

使用<meta http-equiv="content-type"content="text/html;charset=支持中文的編碼">,讓瀏

覽器以規定的編碼打開頁面

表單要采用post提交方式。

                           step2 服務器端使用指定的編碼格式去解碼。request.setCharacterEncoding(指定的編碼);

 注意:只對post請求有效

12、中文參數傳遞亂碼問題?

      自從Tomcat5.x開始,GET和POST方法提交的信息,Tomcat采用了不同的方式來處理編碼

      1)對於POST請求,Tomcat會仍然使用request.setCharacterEncoding方法所設置的編碼來處理,如果

         未設置,則使用默認的iso-8859-1編碼。

      2)而GET請求則不同,Tomcat對GET請求並不會考慮使用request.setCharacterEncoding方法設置的編

         碼,而會永遠使用iso-8859-1編碼,因此,tomcat將會使用iso-8859-1將提交的字節轉換成字符串。

 方法一:(只適合post請求)

    1)<meta http-equiv="content-type"content="text/html;charset=支持中文的編碼">

    2)request.setCharacterEncoding(支持中文的編碼)

  方法二:(get/post都適用)

new String(str.getBytes(“iso-8859-1”),”支持中文的編碼”);

       方法三:(get/post都適用)

1)在傳參數之前先把參數進行轉碼

                   java.net.URLEncoder.encode(param);

                       <a href="ds.jsp?url=

<%=java.net.URLEncoder.encode("編碼的是這里","GB2312")%>"

                       點擊這里

                   </a>   
                       2)取值時再轉回中文

   java.net.URLDecoder.decode(param);

  方法四:(只有get適用)

在你的Tomcat目錄-->conf目錄-->server.xml里找出這段:
      <Connector  port="8080" maxThreads="150" minSpareThreads="25"

          maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               debug="0" connectionTimeout="20000"
               disableUploadTimeout="true"
                  <!--在里邊加上這個參數-->
                  URIEncoding="utf-8"
     />

通知tomcat對於get請求中的參數不再使用iso-8859-1解碼,而是使用utf-8進行

       注意url地址后如果有參數並且參數是中文,就只能用二三四方法

13、重定向

1)什么是重定向?

服務器向瀏覽器發送一個狀態碼302及一個location消息頭(值是一個地址,稱之為重定向地址),

瀏覽器收到后,會立即向 location所指向的地址發送請求。

2)如何重定向

response.sendRedirect(String url); 其中,url是重定向的地址。

3)編程要注意的問題

             a、重定向之前,不能夠有out.close()或者out.flush()操作。(否則會報錯)

   有out.close或者out.flus時,請求經處理后要把處理結果打包響應給瀏覽器。

   而response.sendRect也是對瀏覽器請求的響應,這樣就造成了一次請求兩次響應,不符合規范.

             b、重定向之前,如果response對象緩存有數據,則這些數據會被清空。

   重定向后,只發送一個重定向地址,不會發送實體內容。所以response對象會清空。

   response對象里裝的是返回給瀏覽器的實體內容。

4)重定向的特點

             重定向的地址是任意的

             重定向之后,瀏覽器地址欄的地址變成了location所指定的地址

14、將中文數據插入到數據庫

           將數據插入數據庫的過程是編碼:內存中的編碼是unicode。 

       插入數據庫的過程數據從unicode編碼再變成數據庫的編碼進行入庫。

       從數據庫中取出數據是解碼。

       step1 要保證數據庫正確地設置了字符集,即字符集必須支持中文

       step2 要保證jdbc驅動程序正確地進行了編碼和解碼。

                     jdbc:mysql://localhost:3306/jd1206db?useUnicode=true&characterEncoding=utf8

                     告訴jdbc驅動程序當前數據庫的字符集。

                     因為某些版本的驅動程序不能夠正確地獲知數據庫的字符集設置。        

15、DAO

  DAO,封裝了數據訪問邏輯,調用者不需要了解底層的數據訪問細節就可以實現數據訪問。

  這樣一來,當底層的數據訪問細節發生改變,不會影響到調用者。

如何寫一個DAO?

(1)實體類:為了方便處理數據庫中的記錄,可以定義與記錄對應的實體類,即可以將數據庫中的

                  某條記錄轉換成一個實體類的實例。

                  比如Employee類,提供id,name,salary,age屬性及相關的get/set方法,我們可以將t_emp

                  表中的記錄轉化成一個Employee對象。

(2)DAO接口:

在DAO接口當中,聲明對某個表的所有操作相關的方法。

基本原則: 接口中聲明的方法不要涉及任何具體的實現。

         比如:EmployeeDAO接口,

聲明了: public void save(Employee e) throws SQLException;

這種方式不好,因為出現了jdbc的異常類,這就要求實現該方法只能使用jdbc。

換一種方式來聲明,更好

public void save(Employee e) throws Exception;

public List<Employee> findAll() throws Exception;

     (3)DAO實現類

          采用具體的技術實現DAO接口

          比如:使用jdbc實現EmployeeDAO接口,寫一個類EmployeeDAOIdbcImpl。

     (4)DAO工廠(工廠模式)

         什么是設計模式:是為了解決一類相似的問題提出的解決方案。

                  工廠設計模式:工廠將對象的創建過程對外屏蔽,為調用者提供符合接口要求的對象(產品)。

                  比如:Connection conn = DriverManager.get...

16、處理請求資源路徑

比如輸入:  http://ip:port/appname/abc.html  

servlet處理請求資源路徑的步驟:

       step1、依據/appname查找該應用對應的文件夾(比如查找webapps下面的文件夾是否與其匹配)

  step2、在找到的文件夾下面,找到web.xml文件,然后使用<url-pattern>與/abc.html匹配。

         匹配規則:

精確匹配:即要求<url-pattern>與/abc.html完全一致

通配符匹配:使用“*”代表任意的字符串

        比如在<url-pattern>中使用/*表示任意字符串,/abc/*表示有abc的字符串

后綴匹配:不能使用“/”開頭,要求“*.任意的字符串”。

比如:*.do要求以.do為結尾   *.action要求以.action

        step3、如果都不匹配,嘗試查找/abc.html靜態頁面,如果找到,則返回該文件,找不到,則返回

              404狀態

17、Servlet處理多種請求

 一個servlet如何處理多種請求?

 step1、使用后綴匹配模式。<url-pattern>*.do</url-pattern>

 step2、在service()方法里加入代碼:

         獲得請求資源路徑:String url=request.getRequestURI();

         分析請求資源路徑,來決定做何種處理

//幾種地址的比較 request的方法

ServletPath:/image.jsp

RequestURI:/elec_qin/image.jsp

ContextPath:/elec_qin

RequestURL:http://localhost:8080/elec_qin/image.jsp

18、servlet生命周期相關核心接口與類

 

Servlet的框架是由兩個Java包組成的:javax.servlet與javax.servlet.http。

在javax.servlet包中定義了所有的Servlet類都必須實現或者擴展的通用接口和類。

在javax.servlet.http包中定義了采用Http協議通信的HttpServlet類。

Servlet的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必須實現這個接口。

(1)Servlet接口

在Servlet接口中定義了5個方法,

void  init(ServletConfig config): 初始化

void  service(ServletRequest req,ServletResponse res):

void  destory():

ServletConfig getServletCnifg();

String getServletInfo();

Servlet接口依賴於ServletRequest,ServletResponse,ServletConfig接口

(2)ServletConfig接口

     用來訪問初始化參數。

     當容器讀取web.xml配置文件中<servlet>配置節信息,根據<servlet-class>配置節信息創建servlet

     對象,同時根據<init-param>配置節信息創建ServletConfig對象。然后調用init方法,把創建好的

     ServletConfig對象傳給servlet對象。注意是servlet容器實現了ServletConfig接口。

ServletConfig對象封裝了初始化參數。定義了如下的方法:

public abstract String getServletName();

public abstract ServletContext getServletContext();

public abstract String getInitParameter(String s);

public abstract Enumeration getInitParameterNames();

 (2)GenericServlet抽象類

  GenericServlet實現了Servlet和ServletConfig接口。擁有了兩個接口的所有方法。

  實現servlet接口中的部分方法,主要是實現了init,destroy方法。

  GenericServlet類的主要結構

       1)有一個屬性:private  ServletConfig config;

       2)getServletCnifg()方法,獲得容器創建好的Servletconfig對象

     public ServletConfig getServletConfig(){

return this.config;

        }

容器調用init方法時,將容器創建好的ServletConfig對象賦值給屬性config。

再通過調用getServletConfig方法得到ServletConfig對象。

       3)init方法()的實現

              public void init(ServletConfig config)throw ServletException{

                      this.config=config;//把對象的引用通過屬性保存下來

                      this.init();

 }

         //鈎子方法,存在的意義就是被覆蓋。當servlet要求有復雜的初始化步驟時,覆蓋此方法

 public  void init()throws ServletException(){

//什么都沒有做

 }

  4)service方法沒有實現,由子類實現

 public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse)

  5)實現類destroy方法

                      public void destroy(){ }

  6)也實現了ServletConfig接口的getServletName,getServletContext,getInitParameter,

     getInitParameterNames。

     實現原理是在這些方法中調用了容器創建好的ServletConfig(屬性config)中相應的方法

 (3)HttpServlet抽象類 

 繼承了GenericServlet,主要實現了service方法

 定義doGet(),doPost(),doHead(),doPut(),doDelete(),doOptions()方法。

 根據請求方式來調用相應的doXXX方法。

 實現了GenericServlet的service方法。

 service方法的主要邏輯是根據請求來調用相應的doXXX方法。

 (4)ServletRequest與ServletResponse接口

 (5)HttpServletRequest與HttpServletResponse接口

      HttpServletRequest接口繼承ServletRequest接口

      HttpServletResponse接口繼承ServletResponse接口

 這些接口由servlet容器實現,在請求到達時創建request對象和response對象傳入到service方法中。

 (6)整個過程

      1、Web客戶向Servlet容器(Tomcat)發出Http請求

           2、Servlet容器分析客戶的請求信息

           3、Servlet容器創建一個HttpRequest對象,將客戶請求的信息封裝到這個對象中

           4、Servlet容器創建一個HttpResponse對象

      5、Servlet容器調用HttpServlet對象的service方法,

         把HttpRequest對象與HttpResponse對象作為參數傳給 HttpServlet對象

           6、HttpServlet調用HttpRequest對象的有關方法,獲取Http請求信息

           7、HttpServlet調用HttpResponse對象的有關方法,生成響應數據

      8、Servlet容器把HttpServlet的響應結果傳給Web客戶

19、servlet的生命周期

       所謂生命周期,指的是servlet容器如何創建servlet對象、如何初始化、如何調用servlet對象的方法來

      處理請求以及如何銷毀servlet對象的整個過程。

 1實例化(就是創建servlet對象,調用構造器)

          a、什么是實例化?

容器調用servlet的構造器,創建一個servlet對象。(new一個對象)

  b、什么時候實例化?

          1)當請求到達容器時,容器查找該servlet對象是否存在,如果不存在,才會創建實例。   

          2)容器在啟動時,或者新部署了某個應用時,會檢查web.xml當中,servlet是否有

             load-on-starup配置。如果有,則會創建該servlet實例。

             load-on-starup參數要求是一個>=0的整數,值越小,優先級越高(先被實例化)。

               注意:servlet容器在默認情況下,對於每個servlet,只會創建一個實例。(單例模式)

 2)初始化

      a、什么是初始化?

         servlet容器在創建好servlet對象之后,會立即調用該對象的init方法。

      b、GenericServlet已經提供了init方法,一般情況下,我們不再需要寫init方法了。

GenericServlet提供的init方法是這樣實現的:

將容器提供的ServletConfig對象保存下來,並且提供了getServletConfig方法用來獲得ServletConfig對象。

 c、servlet的初始化參數

    1)使用<init-param>來配置初始化參數

<init-param>

<param-name>company</param-name>

<param-value>北京</param-value

</init-param>

2)調用ServletConfig對象的getInitParameter方法獲得參數值

 d、如何實現自己的初始化方法?

建議override init()方法

 e、init方法只會執行一次

 3)就緒/調用

          a、什么是就緒?

servlet容器在收到請求之后,會調用servlet對象的service方法來處理請求。

  b、HttpServlet的service方法是如何實現的?

     依據請求方式(get/post)分別調用doGet/doPost方法。

         可以覆蓋HttpServlet提供的doGet/doPost方法,也可以直接覆蓋HttpServlet提供的service方法

 4)銷毀

 a、什么是銷毀?

    servlet容器依據自身的算法,在不再需要servlet對象時,會調用該對象的destroy方法,

    然后,再刪除該對象。

    Servlet容器停止或者重新啟動:Servlet容器調用Servlet對象的destroy方法來釋放資源。

 b、GenericServlet已經實現了destroy方法。釋放資源

 c,、該方法只會執行一次。

         在servlet的整個生命周期當中,init,destroy只會執行一次,而service方法會執行多次。

 

20、案例

                1)產品計價

       發送請求:http://localhost:8088/web04_2/pricing.html

            pricing.html

               <body style="font-size:30px;font-style:italic;">

                                             <form action="pricing" method="post">

                                                      <fieldset>

                                                               <legend>產品計價</legend>

                                                               原始價格:<input name="basePrice"/><br/>

                                                               出售城市:<select name="city" style="width:150px;">

                                                                                          <option value="bj">北京</option>

                                                                                          <option value="sh">上海</option>

                                                                                          <option value="cs">長沙</option>

                                                                                 </select><br/>

                                                                                 <input type="submit" value="確定"/>

                                                      </fieldset>

                                             </form>

</body>

  點擊按鈕發送請求:http://localhost:8088/web04_2/pricing

  配置文件web.xml

                                  <servlet>

                                           <servlet-name>pricingServlet</servlet-name>

                                           <servlet-class>web.PricingServlet</servlet-class>

                                           <init-param>

                                                    <param-name>taxRate</param-name>

                                                    <param-value>bj,0.08;sh,0.09;cs,0.03</param-value>

                                           </init-param>

                                  </servlet>

                                  <servlet-mapping>

                                           <servlet-name>pricingServlet</servlet-name>

                                           <url-pattern>/pricing</url-pattern>

       </servlet-mapping>

 類PricingServlet.java

                  public class PricingServlet extends HttpServlet{

                                             private HashMap<String,Double> taxRates =

                                                                                                                     new HashMap<String,Double>();

                                             public void service(HttpServletRequest request, HttpServletResponse response)

                                                                                                            throws ServletException, IOException {

                                                      response.setContentType("text/html;charset=utf-8");

                                                      PrintWriter out = response.getWriter();

                                                      double basePrice = Double.parseDouble(request.getParameter("basePrice"));

                                                      String city = request.getParameter("city");

                                                      double taxRate = taxRates.get(city);

                                                      double price = basePrice * ( 1 + taxRate);

                                                      out.println("實際售價:" + price);

                                             }

                                           public void init() throws ServletException {

                                                      System.out.println("init...初始化,從配置文件中讀取各個城市的利率");

                                                      ServletConfig config = getServletConfig();

                                                      //bj,0.08;sh,0.09;cs,0.03

                                                      String taxRate = config.getInitParameter("taxRate");

                                                      String[] strs = taxRate.split(";");

                                                      for(int i=0;i<strs.length;i++){

                                                               String str = strs[i];  //bj,0.08

                                                               String[] str1 = str.split(",");

                                                               taxRates.put(str1[0], Double.parseDouble(str1[1]));

                                                      }

                                           }

(2)servlet生命周期

<servlet>

                                  <servlet-name>some</servlet-name>

                                  <servlet-class>web.SomeServlet</servlet-class>

                                  <!-- 初始化參數 -->

                                  <init-param>

                                           <param-name>company</param-name>

                                           <param-value>工商銀行</param-value>

                                  </init-param>

                                  <init-param>

                                           <param-name>address</param-name>

                                           <param-value>北京上地</param-value>

                                  </init-param>

                                  <!-- 啟動就加載 參數值越小,優先級越高 -->

                                  <load-on-startup>1</load-on-startup>

</servlet>

public class SomeServlet extends HttpServlet{

                                    public SomeServlet(){

                                             System.out.println("SomeServlet's constructor...");

                                    }

                                  public void init() throws ServletException {

                                             System.out.println("SomeServlet's init...");

                                   }

public void service(HttpServletRequest request,       HttpServletResponse response)

                                                                                                                     throws ServletException,IOException{

                                             System.out.println("SomeServlet's doGet...");���ServletConfig����

                                             ServletConfig config = getServletConfig();

                                             String company = config.getInitParameter("company");

                                             System.out.println("company:" + company);

                                    }

                                  public void destroy() {

                                            System.out.println("SomeServlet's destroy...");

                                   }

   

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM