java 之 Servlet

Servlet簡介

Servlet是sun公司提供的一門用於開發動態web資源的技術。
Sun公司在其API中提供了一個servlet接口,用戶若想開發一個動態web資源(即開發一個Java程序向瀏覽器輸出數據),需要完成以下2個步驟:
編寫一個Java類,實現servlet接口。
把開發好的Java類部署到web服務器中。
快速入門,用servlet向瀏覽器輸出“hello servlet”
閱讀Servlet API,解決兩個問題:
輸出hello servlet的java代碼應該寫在servlet的哪個方法內?
如何向IE瀏覽器輸出數據?

Servlet在web應用中的位置

這裏寫圖片描述

執行過程

客戶端發出請求http://localhost:8080/Demo1/abc
根據web.xml文件的配置,找到<url-pattern>子元素的值“/hello”的<servlet-mapping>元素
讀取<servlet-mapping>元素的<servlet-name>子元素的值,由此確定Servlet的名字爲”HelloServlet”
找到<servlet-name>值爲HelloServlet的<servlet>元素
讀取<servlet>元素的<servlet-class>子元素的值,由此確定Servlet的類名爲cn.itcast.HelloServlet。
到Tomcat安裝目錄/webapps/Demo1/WEB-INF/classes/cn/itcast目錄下查找到HelloServlet.class文件

執行過程圖解

這裏寫圖片描述

Servlet的運行過程

Servlet程序是由WEB服務器調用,web服務器收到客戶端的Servlet訪問請求後:
    Web服務器首先檢查是否已經裝載並創建了該Servlet的實例對象。如果是,則直接執行第④步,否則,執行第②步。
    裝載並創建該Servlet的一個實例對象。 
    調用Servlet實例對象的init()方法。
    創建一個用於封裝HTTP請求消息的HttpServletRequest對象和一個代表HTTP響應消息的HttpServletResponse對象,然後調用Servlet的service()方法並將請求和響應對象作爲參數傳遞進去。
    WEB應用程序被停止或重新啓動之前,Servlet引擎將卸載Servlet,並在卸載之前調用Servlet的destroy()方法。

在Eclipse中開發Servlet

這裏寫圖片描述

Servlet接口實現類

Servlet接口SUN公司定義了兩個默認實現類,分別爲:GenericServlet、HttpServlet。

HttpServlet指能夠處理HTTP請求的servlet,它在原有Servlet接口上添加了一些與HTTP協議處理方法,它比Servlet接口的功能更爲強大。因此開發人員在編寫Servlet時,通常應繼承這個類,而避免直接去實現Servlet接口。

HttpServlet在實現Servlet接口時,覆寫了service方法,該方法體內的代碼會自動判斷用戶的請求方式,如爲GET請求,則調用HttpServlet的doGet方法,如爲Post請求,則調用doPost方法。因此,開發人員在編寫Servlet時,通常只需要覆寫doGet或doPost方法,而不要去覆寫service方法。

Servlet的一些細節(1)

這裏寫圖片描述

Servlet的一些細節(2)

這裏寫圖片描述

Servlet的一些細節(3)

這裏寫圖片描述

Servlet的一些細節(4)

這裏寫圖片描述

Servlet的生命週期

    Servlet是一個供其他Java程序(Servlet引擎)調用的Java類,它不能獨立運行,它的運行完全由Servlet引擎來控制和調度。

    針對客戶端的多次Servlet請求,通常情況下,服務器只會創建一個Servlet實例對象,也就是說Servlet實例對象一旦創建,它就會駐留在內存中,爲後續的其它請求服務,直至web容器退出,servlet實例對象纔會銷燬。

    在Servlet的整個生命週期內,Servlet的init方法只被調用一次。而對一個Servlet的每次訪問請求都導致Servlet引擎調用一次servlet的service方法。對於每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然後將這兩個對象作爲參數傳遞給它調用的Servlet的service()方法,service方法再根據請求方式分別調用doXXX方法。 

如果在<servlet>元素中配置了一個<load-on-startup>元素,那麼WEB應用程序在啓動時,就會裝載並創建Servlet的實例對象、以及調用Servlet實例對象的init()方法。
舉例:
<servlet>
    <servlet-name>invoker</servlet-name>
    <servlet-class>
        org.apache.catalina.servlets.InvokerServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

用途:爲web應用寫一個InitServlet,這個servlet配置爲啓動時裝載,爲整個web應用創建必要的數據庫表和數據

Servlet的線程安全

當多個客戶端併發訪問同一個Servlet時,web服務器會爲每一個客戶端的訪問請求創建一個線程,並在這個線程上調用Servlet的service方法,因此service方法內如果訪問了同一個資源的話,就有可能引發線程安全問題。

    如果某個Servlet實現了SingleThreadModel接口,那麼Servlet引擎將以單線程模式來調用其service方法。
    SingleThreadModel接口中沒有定義任何方法,只要在Servlet類的定義中增加實現SingleThreadModel接口的聲明即可。  
    對於實現了SingleThreadModel接口的Servlet,Servlet引擎仍然支持對該Servlet的多線程併發訪問,其採用的方式是產生多個Servlet實例對象,併發的每個線程分別調用一個獨立的Servlet實例對象。

    實現SingleThreadModel接口並不能真正解決Servlet的線程安全問題,因爲Servlet引擎會創建多個Servlet實例對象,而真正意義上解決多線程安全問題是指一個Servlet實例對象被多個線程同時調用的問題。事實上,在Servlet API 2.4中,已經將SingleThreadModel標記爲Deprecated(過時的)。

解決併發問題

解決併發出現的問題,可以採用以下方式:
使用Java同步機制對多線程同步:運行效率低
使用SingleThreadModel接口
合理決定在Servlet中定義的變量的作用域

ServletConfig對象

    在Servlet的配置文件中,可以使用一個或多個<init-param>標籤爲servlet配置一些初始化參數。

    當servlet配置了初始化參數後,web容器在創建servlet實例對象時,會自動將這些初始化參數封裝到ServletConfig對象中,並在調用servlet的init方法時,將ServletConfig對象傳遞給servlet。進而,程序員通過ServletConfig對象就可以得到當前servlet的初始化參數信息。

閱讀ServletConfig API,並舉例說明該對象的作用:
    獲得字符集編碼
    獲得數據庫連接信息

ServletContext

    WEB容器在啓動時,它會爲每個WEB應用程序都創建一個對應的ServletContext對象,它代表當前web應用。

    ServletConfig對象中維護了ServletContext對象的引用,開發人員在編寫servlet時,可以通過ServletConfig.getServletContext方法獲得ServletContext對象。

    由於一個WEB應用中的所有Servlet共享同一個ServletContext對象,因此Servlet對象之間可以通過ServletContext對象來實現通訊。ServletContext對象通常也被稱之爲context域對象。

    查看ServletContext API文檔,瞭解ServletContext對象的功能

ServletContext應用

多個Servlet通過ServletContext對象實現數據共享。
獲取WEB應用的初始化參數。
實現Servlet的轉發。
利用ServletContext對象讀取資源文件。
    .properties文件(屬性文件)
    得到文件路徑(ServletContext.getRealPath(),ServletContext.getReaourceAsStream())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章