Servlet---JavaWeb技術的核心基礎

(我的轉載)

        初學JavaWeb開發,請遠離各類框架,從Servlet開始。html

        Web框架是開發者在使用某種語言編寫Web應用服務端是關於架構的最佳實踐。不少Web框架是從實際的Web項目抽取出來的,僅和Web的請求和響應處理有關,造成一個基礎,在開發別的應用項目的時候則能夠從這個剝離出來的基礎作起,讓開發者更關注具體的業務問題,而不是Web的請求和響應的控制。
        框架不少,但套路基本相似,幫你隱藏不少關於HTTP協議細節內容,專一功能開發。
        但對於一個初學者來講,過早的接觸框架每每事倍功半!一樣一個問題,換一種框架你可能須要從頭開始研究。
        因此,做爲Java Web技術的核心基礎,Servlet的工做原理是必須掌握的,也是成爲一名合格的Java Web技術開發人員的基本要求。
 
1、Servlet簡介
        Servlet是Server與Applet的縮寫,是服務端小程序的意思。是SUN公司提供的一門用於開發動態Web資源的技術。目前最新版本爲3.1。
        Servlet本質上也是Java類,但要遵循Servlet規範進行編寫,沒有main()方法,它的建立、使用、銷燬都由Servlet容器進行管理(如Tomcat)。
        Servlet是和HTTP協議是緊密聯繫的,其能夠處理HTTP協議相關的全部內容。這也是Servlet應用普遍的緣由之一。
        提供了Servlet功能的服務器,叫作Servlet容器,其常見容器有不少,如Tomcat, Jetty, resin, Oracle Application server, WebLogic Server, Glassfish, Websphere, JBoss等。
 
2、Servlet工做原理解析
        一、一個HTTP請求的執行過程:
           客戶端發出請求 http://localhost:8080/xxx
           根據Web.xml文件的配置,找到<url-pattern>對應的<servlet-mapping>
           讀取<servlet-mapping>中<servlet-name>的值
           找到<servlet-name>對應的<servlet-class>
           找到該class並加載執行該class
        二、Servlet的執行過程
           Servlet程序有Web服務器調用,當收到請求後,
           檢查是否已裝載並建立了該Servlet對象,若是沒有則加載建立
           調用Servlet的init()方法初始化實例
           調用service()方法,處理請求並返回響應結果
           在服務器被中止或重啓以前,調用destroy()方法釋放資源
        三、Servlet接口實現類
           SUN公司定義了兩個實現類,GenerricServlet和HttpServlet,其中後者是前者的子類,它在原有基礎上添加了一些HTTP協議處理方法,它比GenerricServlet功能更強大,因此咱們通常將本身的類繼承自HttpServlet,並重寫doGet方法和doPost方法,不須要重寫Service方法。
         四、Servlet的一些細節
               4.一、因爲客戶端是經過URL地址訪問web服務器中的資源,因此Servlet程序弱項被外界訪問,必須把Servlet程序映射到一個URL地址上,這個工做在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成(在Servlet3.0規範的新特性中,該功能可使用註解完成,不要求必須使用web.xml,只用註解更簡單,該特性會在後文進行詳細講解)。
                    <servlet>元素用於註冊Servlet,它包含兩個主要的子元素:<servlet-name>和<servlet-class>,分別用於設置Servlet的註冊名稱和Servlet的完整類名。
                    <servlet-mapping>元素用於映射一個已註冊的Servlet的一個對外訪問路徑,它包含兩個子元素:<servlet-name>和<url-pattern>,分別用於指定Servlet的註冊名稱和Servlet的對外訪問路徑。
  1. 複製代碼
    <web-app>
        <servlet>
            <servlet-name>AnyName</servlet-name><!--自定義的邏輯名-->
            <servlet-class>HelloServlet</servlet-class><!--Servlet對應類的全類名-->
        </servlet>
        <servlet-mapping>
            <servlet-name>AnyName</servlet-name><!--上面定義的邏輯名-->
            <url-pattern>/demo/hello.html</url-pattern><!--匹配的URL-->
        </servlet-mapping>
    </web-app>
    複製代碼

                 4.二、同一個Servlet能夠被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設置值能夠是同一個Servlet的註冊名。java

                  在Servlet映射到的URL中也可使用*通配符,可是隻能有兩種固定的格式:
                  一種是「*.擴展名」。
                  另外一種是以(/)開頭並以(/*)結尾。
  1. 複製代碼
    <!--方式一用於匹配全部某一擴展名的文件-->
    <servlet-mapping>
        <servlet-name>AnyName</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <!--方式二用於匹配某一文件夾下的全部文件-->
    <servlet-mapping>
        <servlet-name>AnyName</servlet-name>
        <url-pattern>/action/*</url-pattern>
    </servlet-mapping>
    複製代碼

                       兩個特色:能夠精確匹配,就用精確匹配,最後使用範圍最寬泛的匹配web

                                 /* 的優先級高於 *.擴展名 會先匹配
              4.三、若是某個Servlet的映射路徑只有一個(/),那麼這個Servlet就成爲當前Web應用程序的缺省Servlet。
                    凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它們的請求訪問都將交給缺省Servlet處理,也就是說,缺省Servlet用於處理全部其餘Servlet都不處理的訪問請求。
                    在tomcat的安裝目錄/conf/web.xml中,註冊了一個名稱org.apache.catalina.servlets.DefaultServlet的Servlet,並將這個Servlet設置爲缺省Servlet。
                    當訪問Tomcat服務器中的某個靜態HTML文件或圖片等資源時,其實是在訪問這個缺省Servlet。
          五、Servlet的生命週期
              Servlet沒有main()方法,不能獨立運行,它的運行徹底由Servlet引擎來控制和調度。
              針對客戶端的屢次Servlet請求,一般狀況下,服務器只會在第一次請求的時候建立一個Servlet實例對象,並駐留在內存中,爲後續的其餘請求服務,直至web容器退出,Servlet實例對象纔會銷燬。
              在Servlet的整個生命週期內,Servlet的init()方法只被調用一次,而對於每個請求都會調用一次Servlet的service()方法service根據請求方式調用doGet或doPost方法
              若是在<servlet>元素中配置了一個<load-on-startup>元素,那麼WEB應用程序在啓動時,就會裝載並建立實例對象、以及調用Servlet實例對象的init()方法。能夠在啓動的時候爲整個WEB應用建立一些必要的的資源或鏈接。但若是全部的Servlet都啓動加載,則會大大增長服務器負擔,並且有些Servlet永遠也不會被客戶訪問到,白白浪費資源,因此從性能角度,應合理利用該特性。
複製代碼
<servlet>
    <servlet-name>invoker</servlet-name>
    <servlet-class>
            org.apache.catalina.servlets.InvokerServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup><!--數字表示啓動加載的優先級,大於0-->
</servlet>
複製代碼

          六、ServletConfig對象apache

                在Servlet的配置文件中,可使用一個或對個<init-param>標籤爲Servlet配置一些初始化參數。
                當Servlet配置了初始化參數後,web容器在建立Servlet實例對象時,會自動將這些初始化參數封裝到ServletConfig對象中,並在調用Servlet的init方法時,將ServletConfig對象傳似給Servlet,開發者能夠經過ServletConfig對象獲得初始化參數信息。
           七、ServletContext對象
                WEB容器在啓動時,它會爲每一個WEB應用程序都建立一個對應的Servlet對象,它表明當前web應用。
                ServletConfig對象中維護了ServletContext對象的引用,開發者在編寫Servlet是,能夠經過ServletConfig.getServletContext方法得到該對象。
                因爲一個WEB應用中的全部Servlet共享同一個ServletContext對象,所以Servlet對象之間能夠經過ServletContext對象來實現通信。ServletContext對象一般也被稱之爲Context域對象。
                 多個Servlet經過ServletContext對象實現數據共享。要確保注意線程安全。
                 能夠經過ServletContext對象獲取WEB應用的初始化參數。
                 能夠實現Servlet的轉發。getRequestDispatcher()方法
          八、Servlet經常使用容器Tomcat(左圖:Tomcat容器;右圖:Servlet的執行流程)
                 
          九、 Servlet體系結構
               
             從上圖能夠看出Servlet規範是基於這幾個類運轉的,與Servlet主動關聯的是三個類:ServletConfig、ServletRequest、ServletResponse。這三個類都是經過容器傳遞給Servlet的。
             ServletConfig接口中的方法都是爲了獲取這個Servlet的一些配置屬性,而這些配置屬性可能在Servlet運行時被用到。
             ServletContext就是這些配置屬性的上下文環境。
 
3、Servlet中的Session與Cookie
           Servlet可以給咱們提供兩部分數據,一個是在Servlet初始化時調用init方法設置的ServletConfig,它基本包含了Servlet自己和Servlet所運行的Servlet容器中的基本信息。另外一個是ServletRequest提供的此次請求的HTTP協議信息,這部分須要很清楚HTTP協議。
           Session與Cookie的做用都是爲了保持訪問用戶與後端服務器的交互狀態,各有優缺點。然而具備諷刺意味的是它們優勢和它們的使用場景又是矛盾的,例如使用 Cookie 來傳遞信息時,隨着 Cookie 個數的增多和訪問量的增長,它佔用的網絡帶寬也很大,試想假如 Cookie 佔用 200 個字節,若是一天的 PV 有幾億的時候,它要佔用多少帶寬。因此大訪問量的時候但願用 Session,可是 Session 的致命弱點是不容易在多臺服務器之間共享,因此這也限制了 Session 的使用。

           Session正常工做的實現方式:小程序

               基於URL Path Parameter,默認支持
               基於Cookie,若不修改Context中的cookie標識,默認支持
               基於SSL,默認不支持,只有connector.getAttribute("SSLEnabled")爲true時才支持。
 
4、Servlet中的Listener
        整個Tomcat服務器中Listener使用的很是普遍,它是基於觀察者模式的,Listener的設計對開發Servlet應用程序提供了一種快捷的手段,可以方便的從另外一個縱向惟獨控制程序和數據,目前Servlet中提供了5中兩類事件的觀察者接口,他們分別是:4個EventListener類型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener 和 2 個 LifecycleListeners 類型的,ServletContextListener、HttpSessionListener。
           它們基本上涵蓋了整個Servlet生命週期中,你感興趣的每種事件,這些Listener的實現類能夠配置在web.xml中的<listener>標籤中,固然也能夠在應用程序中動態添加Listener,可是ServletContextListener在容器啓動以後就不能再添加新的,由於它監聽的事件已經不會再出現。掌握這些Listener的使用,可以讓咱們的程序設計的更加靈活。
 
5、Servlet3.0新特性註解
         前面介紹過Servlet3.0提供了註解(annotation),使得再也不須要在web.xml文件中進行Servlet的部署描述。
        開發者可使用@WebServlet註解將一個繼承於javax.servlet.http.HttpServlet的類標註爲能夠處理用戶請求的Servlet。   
  @WebServlet註解的相關屬性
NO. 屬性名 描述
1 asyncSupported 聲明Servlet是否支持異步操做模式
2 description Servlet的描述信息
3 displayName Servlet的顯示名稱
3 initParams Servlet的初始化參數
5 name Servlet的名稱
6 urlPatterns Servlet的訪問URL
7 value Servlet的訪問URL

         Servlet的訪問URL是Servlet的必選屬性,能夠選擇使用urlPatterns或者value定義。後端

         更多關於Servlet3.0的註解使用知識請參考博客:
相關文章
相關標籤/搜索