<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-57  評論-117  文章-1  trackbacks-0

    Servlet 是一種比JSP 更早的動(dòng)態(tài)網(wǎng)頁編程技術(shù)。在沒有JSP 之前, Servlet 也是同時(shí)充當(dāng)視圖層、業(yè)務(wù)邏輯層及持久層角色。

    Servlet 的開發(fā)效率非常低,特別是當(dāng)使用Servlet 生成表現(xiàn)層頁面時(shí),頁面中所有的HTML 標(biāo)簽,都需采用Servlet 的輸出流來輸出,因此極其煩瑣。由于Servlet 是個(gè)標(biāo)準(zhǔn)的Java 類,因此必須由程序員開發(fā),其修改難度大,美工人員根本無法參與Servlet 頁面的開發(fā)。這一系列的問題,都阻礙了Servlet 作為表現(xiàn)層的使用。

    自MVC 規(guī)范出現(xiàn)后, Servlet 的責(zé)任開始明確下來,僅僅作為控制器使用,不再需要生成頁面標(biāo)簽,也不再作為視圖層角色使用。

     

    Servlet ,通常稱為服務(wù)器端小程序,是運(yùn)行在服務(wù)器端的程序,用于處理及響應(yīng)客戶端請求。

    Servlet 是個(gè)特殊的Java 類,這個(gè)Java 類必須繼承HttpServlet 。每個(gè)Servlet 可以響應(yīng)戶端的請求。Servlet 提供不同的方法用于響應(yīng)客戶端請求。

    doGet: 用于響應(yīng)客戶端的get 請求。

    doPost: 用于響應(yīng)客戶端的post 請求。

    doPut: 用于響應(yīng)客戶端的put 請求。

    doDelete: 用于響應(yīng)客戶端的delete 請求。

    事實(shí)上,客戶端的請求通常只有g(shù)et 和post 兩種; Servlet 為了響應(yīng)這兩種請求,必須重寫doGet 和doPost 兩個(gè)方法。如果Servlet 為了響應(yīng)四個(gè)方法,則需要同時(shí)重寫上面的四個(gè)方法。

     

    大部分時(shí)候, Servlet 對于所有請求的響應(yīng)都是完全一樣的。此時(shí),可以采用重寫一個(gè)方法來代替上面的幾個(gè)方法, Servlet 只需重寫service 方法即可響應(yīng)客戶端的所有請求。另外, HttpServlet 還包含兩個(gè)方法。

    init(ServletConfig config): 創(chuàng)建Servlet 實(shí)例時(shí),調(diào)用的初始化方法。

    destroy: 銷毀Servlet 實(shí)例時(shí),自動(dòng)調(diào)用的資源回收方法。

    通常無須重寫init和destroy兩個(gè)方法,除非需要在初始化Servlet 時(shí),完成某些資源初始化的方法,才考慮重寫init 方法。如果需要在銷毀Servlet 之前,先完成某些資源的回收,比如關(guān)閉數(shù)據(jù)庫連接等,才需要重寫destroy 方法。

    注意:如果重寫了init(ServletConfig config)方法,則應(yīng)在重寫該方法的第一行調(diào)用super.init(config) 。該方法將調(diào)用HttpServlet 的init 方法。

     

    Servlet 和JSP 的區(qū)別在于:

    Servlet 中沒有內(nèi)置對象,原來JSP 中的內(nèi)置對象都必須通過HttpServletRequest對象,或由HttpServletResponse 對象生成:

    對于靜態(tài)的HTML 標(biāo)簽, Servlet 都必須使用頁面輸出流逐行輸出。

    這也正是筆者在前面介紹的: JSP 是Servlet 的一種簡化,使用JSP 只需要完成程序員需要輸出到客戶端的內(nèi)容,至于JSP 中的Java 腳本如何鑲嵌到一個(gè)類中,由JSP 容器完成。而Servlet 則是個(gè)完整的Java 類,這個(gè)類的service 方法用于生成對客戶端的響應(yīng)。

     

    Servlet 的配置

    編輯好的Servlet 源文件并不能響應(yīng)用戶請求,還必須將其編譯成class 文件。將編譯后的HelloServlet. class 文件放在WEB-INF/classes 路徑下,如果Servlet 有包,則還應(yīng)該將class 文件放在對應(yīng)的包路徑下。

    為了讓Servlet 能響應(yīng)用戶請求,還必須將Servlet 配置在Web 應(yīng)用中。配置Servlet時(shí),需要修改web.xrnl 文件。

    配置Servlet 需要配置兩個(gè)部分。<servlet>/<servlet-mapping>

     

    Servlet的生命周期

    Servlet 在容器中運(yùn)行,其實(shí)例的創(chuàng)建及銷毀等都不是由程序員決定的,而是由容器進(jìn)行控制。

    Servlet 的創(chuàng)建有兩個(gè)選擇。

    客戶端請求對應(yīng)的Servlet 時(shí),創(chuàng)建Servlet 實(shí)例:大部分的Servlet 都是這種Servlet。 Web 應(yīng)用啟動(dòng)時(shí),立即創(chuàng)建Servlet 實(shí)例:即load-on-startup Servlet。

    每個(gè)Servlet 的運(yùn)行都遵循如下生命周期。

    (1)創(chuàng)建Servlet 實(shí)例。

    (2) Web 容器調(diào)用Servlet 的init 方法,對Servlet 進(jìn)行初始化。

    (3) Servlet 初始化后,將一直存在于容器中,用于響應(yīng)客戶端請求。如果客戶端有g(shù)et 請求,容器調(diào)用Servlet 的doGet 方法處理并響應(yīng)請求。對于不同的請求,有不同的處理方法,或者統(tǒng)一使用service 方法處理來響應(yīng)用戶請求。

    (4) Web 容器角色銷毀Servlet 時(shí),調(diào)用Servlet 的destroy 方法,通常在關(guān)閉Web容器之時(shí)銷毀Servlet。

     

    使用Servlet創(chuàng)作為控制器

    正如前面見到,使用Servlet 作為表現(xiàn)層的工作量太大,所有的HTML 標(biāo)簽都需要使用頁面輸出流生成。因此,使用Servlet 作為表現(xiàn)層有如下三個(gè)劣勢。

    開發(fā)效率低,所有的HTML 標(biāo)簽都需使用頁面輸出流完成。

    不利于團(tuán)隊(duì)協(xié)作開發(fā),美工人員無法參與Servlet 界面的開發(fā)。

    程序可維護(hù)性差,即使修改一個(gè)按鈕的標(biāo)題,都必須重新編輯Java 代碼,并重新編譯。

     

    整個(gè)結(jié)構(gòu)非常清晰,下面是MVC 中各個(gè)角色的對應(yīng)組件。

    M: Model,即模型,對應(yīng)JavaBean 。

    V: View ,即視圖,對應(yīng)JSP 頁面。

    C: Controller,即控制器,對應(yīng)Servlet。

     

    load-on-startup Servlet

    Servlet 的實(shí)例化有兩個(gè)時(shí)機(jī):用戶請求之時(shí),或應(yīng)用啟動(dòng)之時(shí)。應(yīng)用啟動(dòng)時(shí)就啟動(dòng)的Servlet 通常是用于某些后臺服務(wù)的Servlet ,或者攔截很多請求的Servlet; 這種Servlet 通常作為應(yīng)用的基礎(chǔ)Servlet 使用,提供重要的后臺服務(wù)。如果需要Web 應(yīng)用啟動(dòng)時(shí),可使用load-on-startup 元素完成Servlet 的初始化。load-on-startup 元素只接收一個(gè)整型值,這個(gè)整型值越小, Servlet 就越優(yōu)先初始化。

    訪問Servlet 的配置參數(shù)

    配置Servlet 時(shí),還可以增加附加的配置參數(shù)。通過使用配置參數(shù),可以實(shí)現(xiàn)更好地解耦,避免將所有的參數(shù)以硬編碼方式寫在程序中。

    訪問Servlet 配置參數(shù)要通過ServletConfig 類的實(shí)例完成, ServletConfig提供如下方法。

    java.lang.String getInitParameter(java.lang.String name): 用于獲取初始化參數(shù)。

    注意: JSP 的內(nèi)直對象config 就是此處的ServletConfig

    自定義標(biāo)簽類

    使用標(biāo)簽類,可以使用簡單的標(biāo)簽來封裝復(fù)雜的功能,從而使團(tuán)隊(duì)更好地協(xié)作開發(fā)(能讓美工人員更好地參與JSP 頁面的開發(fā))。

    自定義標(biāo)簽類都必須繼承一個(gè)父類: java.Servlet.jsp.tagext.TagSupport 。除此之外,自定義標(biāo)簽類還有如下要求。

    ·如果標(biāo)簽類包含屬性,每個(gè)屬性都有對應(yīng)的getter 和setter 方法。

    ·重寫doStartTag或doEndTag方法,這兩個(gè)方法生成頁面內(nèi)容。

    ·如果需要在銷毀標(biāo)簽之前完成資源回收,則重寫re1ease方法。

    TLD 文件

    TLD 是Tag Library Definition 的縮寫,即標(biāo)簽庫定義,文件的后綴是tld ,每個(gè)TLD文件對應(yīng)一個(gè)標(biāo)簽庫,一個(gè)標(biāo)簽庫中可包含多個(gè)標(biāo)簽。TLD 文件也稱為標(biāo)簽庫定義文件。標(biāo)簽庫定義文件的根元素是taglib,它可以有多個(gè)tag 子元素,每個(gè)tag 子元素都對應(yīng)一個(gè)標(biāo)簽。

    編輯了標(biāo)簽庫定義文件還不夠, Web 容器還無法加載標(biāo)簽庫定義文件。還必須在web.xml 文件中增加標(biāo)簽庫的定義。在web.xml 文件中定義標(biāo)簽庫時(shí)使用taglib 元素,該元素包含兩個(gè)子元素: taglib-uri和taglib-location,前者確定標(biāo)簽庫的URI; 后者確定標(biāo)簽庫定義文件的位置。

    使用標(biāo)簽庫

    使用標(biāo)簽庫分成以下兩步。

    (1) 導(dǎo)入標(biāo)簽庫:使用taglib 編譯指令導(dǎo)入標(biāo)簽。

    (2) 使用標(biāo)簽:在JSP 頁面中使用自定義標(biāo)簽。

    taglib 的語法格式如下:

    〈%@ taglib uri="tagliburi" prefix="tagPrefix" %〉

    其中uri 屬性確定標(biāo)簽庫定義文件的URI,這個(gè)URI 就是在web.xml 文件中為標(biāo)簽

    庫定義的URI。而prefix 屬性確定的是標(biāo)簽前綴,即在JSP 頁面中使用標(biāo)簽時(shí),該標(biāo)簽

    庫負(fù)責(zé)處理的標(biāo)簽前綴。

    使用標(biāo)簽的語法格式如下:

    <tagPrefix : tagName tagAttribute=ntagValue n ...>

    <tagBody/>

    </tagPrefix>

    如果該標(biāo)簽沒有標(biāo)簽體,則可以使用如下語法格式:

    <tagPrefix : tagName tagAttribute=ntagValue n …/>

    帶標(biāo)簽體的標(biāo)簽

    帶標(biāo)簽體的標(biāo)簽,就是允許在標(biāo)簽內(nèi)嵌套標(biāo)簽,通常可用于完成一些邏輯運(yùn)算例如判斷和循環(huán)等。

    帶標(biāo)簽體的標(biāo)簽需要繼承BodyTagSupport,該類包含一個(gè)bodyContent 屬性,該屬性代表標(biāo)簽體。

    BodyTagSupport 還包含兩個(gè)方法。

    doAfterBody: 每次處理完標(biāo)簽體后調(diào)用該方法。

    void doInitBody: 開始調(diào)用標(biāo)簽體時(shí)調(diào)用該方法。

    如果有必要,可以重寫這兩個(gè)方法。

    在處理標(biāo)簽類的各個(gè)方法中,不同的返回值對應(yīng)不同的含義,常用的返回值有如下幾個(gè)。

    SKIP_BODY: 不處理標(biāo)簽體,直接調(diào)用doEndTag方法。

    SKIP_PAGE: 忽略標(biāo)簽后面的JSP 頁面。

    EVAL_PAGE: 處理標(biāo)簽結(jié)束,直接處理頁面內(nèi)容。

    EVAL_BODY_BUFFERED: 處理標(biāo)簽體。

    EVAL_BODY_INCLUDE: 處理標(biāo)簽體,但忽略setBodyContent和doInitBody方法。

    EVAL_BODY_AGAIN: 對標(biāo)簽體循環(huán)處理。

     

    Filter

    Filter 并不是一個(gè)標(biāo)準(zhǔn)的Servlet ,它不能處理用戶請求,也不能對客戶端生成響應(yīng)。主要用于對HttpServletRequest 進(jìn)行預(yù)處理,也可以對HttpServletResponse 進(jìn)行后處理,是個(gè)典型的處理鏈。

    Filter 有如下幾個(gè)用處。

    ·在HttpServletRequest 到達(dá)Servlet 之前,攔截客戶的HttpServletRequest 。

    ·根據(jù)需要檢查HttpServletRequest ,也可以修改HttpServletRequest 頭和數(shù)據(jù)。

    ·在HttpServletResponse 到達(dá)客戶端之前,攔截HttpServletResponse 。

    ·根據(jù)需要檢查HttpServletResponse ,也可以修改HttpServletResponse 頭和數(shù)據(jù)。

    Filter 有如下幾個(gè)種類。

    ·用戶授權(quán)的Filter: Filter 負(fù)責(zé)檢查用戶請求,根據(jù)請求過濾用戶非法請求。

    ·日志Filter: 詳細(xì)記錄某些特殊的用戶請求。

    ·負(fù)責(zé)解碼的Filter: 包括對非標(biāo)準(zhǔn)編碼的請求解碼。

    .能改變XML 內(nèi)容的XSLTFilter 等。

    一個(gè)Filter 可負(fù)責(zé)攔截多個(gè)請求或響應(yīng):一個(gè)請求或響應(yīng)也可被多個(gè)請求攔截。

    創(chuàng)建一個(gè)Filter 只需兩個(gè)步驟:

    (1)創(chuàng)建Filter 處理類:

    (2) 在web.xml 文件中配置Filter。

    創(chuàng)建Filter 類

    創(chuàng)建Filter 必須實(shí)現(xiàn)javax.servle t. Filter 接口,在該接口中定義了三個(gè)方法。

    void init(FilterConfig config): 用于完成Filter 的初始化。

    void destroy: 用于Filter 銷毀前,完成某些資源的回收。

    void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 實(shí)現(xiàn)過濾功能,該方法就是對每個(gè)請求及響應(yīng)增加的額外處理。

    執(zhí)行chain.doFilter(request,reponse)方法,當(dāng)Filter 對請求過濾后,依然將請求發(fā)送到目的地址。如果檢查權(quán)限,可以在Filter 中根據(jù)用戶請求的HttpSession,判斷用戶權(quán)限是否足夠。

    如果權(quán)限不夠,則調(diào)用重定向即可,無須調(diào)用chain.doFilter(request,reponse)方法。

    配置Filter

    Filter 的配置和Servlet 的配置非常相似,都需要配置兩個(gè)部分:

    ·配置Filter 名。

    ·配置Filter 攔截URL 模式。

    區(qū)別在于, Servlet 通常只配置一個(gè)URL ,而Filter 可以同時(shí)攔截多個(gè)請求的URL。

    因此,可以配置多個(gè)Filter 攔截模式。

     

    Listener

    Listener 的作用非常類似于load-on-startup Servlet。用于在Web 應(yīng)用啟動(dòng)時(shí),啟動(dòng)某些后臺程序,這些后臺程序負(fù)責(zé)為系統(tǒng)運(yùn)行提供支持。

    Listener 與load-on-startup Servlet 的區(qū)別在于: Listener 的啟動(dòng)時(shí)機(jī)比load-on-startup Servlet 早,只是Listener 是Servlet 2.3 規(guī)范之后才出現(xiàn)的。

    使用Listener 只需要兩個(gè)步驟:

    (1) 創(chuàng)建Listener 實(shí)現(xiàn)類。

    (2) 在web.xml 文件中配置Listener。

    創(chuàng)建Listener 類

    創(chuàng)建Li stener 類必須實(shí)現(xiàn)ServletContex tListener 接口,該接口包含兩個(gè)方法。

    eontextInitialized(ServletContextEvent see): 啟動(dòng)Web 應(yīng)用時(shí),系統(tǒng)調(diào)用該Filter的方法。

    eontextDestroyed(ServletContextEvent see): 關(guān)閉Web 應(yīng)用時(shí)候,系統(tǒng)調(diào)用Filter

    的方法。

    配置Listener

    正如load-an-startup Servlet 一樣, Listener 用于啟動(dòng)Web 應(yīng)用的后臺服務(wù)程序,但不負(fù)責(zé)處理及響應(yīng)用戶請求,因此無須配置URL。

    若將Listener 配置在Web 容器中(如果Web 容器支持Listener),則Listener 將隨Web 應(yīng)用的啟動(dòng)而啟動(dòng)。

    配置Listener 時(shí)使用<listener/>元素,下面是配置Listener 的片段:

    <!-- 配置Listener-->

    <listener>

    <!- 指定Listener 的實(shí)現(xiàn)類→

    <listener-class>lee.ScheduleListener</listener-class>

    </listener>

    在上面的配置中,既無須配置Listener 的名字,也無須配置Listener 的URL 只需配置它的實(shí)現(xiàn)類即可。此時(shí)容器將自動(dòng)檢測部署在容器中的Listener,并在應(yīng)用啟動(dòng)時(shí),自動(dòng)加載所有的Listener。



    作者:hoojo
    出處:
    blog:http://blog.csdn.net/IBM_hoojo
             http://hoojo.cnblogs.com
    本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。


    版權(quán)所有,轉(zhuǎn)載請注明出處 本文出自:
    分享道版權(quán)所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處,謝謝
    posted on 2012-01-29 15:50 hoojo 閱讀(2199) 評論(5)  編輯  收藏 所屬分類: JavaEEJsp/Servlet

    評論:
    # re: Servlet 手記[未登錄] 2012-01-30 10:56 | tbw
    不錯(cuò) 一直關(guān)注   回復(fù)  更多評論
      
    # re: Servlet 手記 2012-02-01 15:19 | 日出星辰
    差距!使用Java快2年了,servlet&jsp是每個(gè)java開發(fā)人員必須會(huì)的,但樓主能把這么簡單的東西總結(jié)的這么詳細(xì)、明白,自嘆不如!
    越簡單的東西越重要啊!向樓主學(xué)習(xí)!  回復(fù)  更多評論
      
    # re: Servlet 手記 2012-02-01 16:22 | hoojo
    @日出星辰
    也是看書、加上之前開發(fā)總結(jié)的一下基礎(chǔ)性的東西,謝謝支持~  回復(fù)  更多評論
      
    # re: Servlet 手記 2012-02-03 23:39 | allenny
    Servlce和JSP的區(qū)別總結(jié)的一塌糊涂  回復(fù)  更多評論
      
    # re: Servlet 手記 2012-02-11 13:35 | hoojo
    @allenny
    怎么講~也只是籠統(tǒng)的概括下  回復(fù)  更多評論
      
    主站蜘蛛池模板: 国产97视频人人做人人爱免费| 亚洲图片在线观看| 成人免费无码精品国产电影| 久久福利资源网站免费看| 99视频在线看观免费| 少妇人妻偷人精品免费视频| 午夜免费福利片观看| 特级精品毛片免费观看| 日韩在线永久免费播放| 日韩人妻一区二区三区免费| 日韩免费高清大片在线| 18禁成人网站免费观看| 国产男女爽爽爽爽爽免费视频| 国产精品视频免费观看| 性生交片免费无码看人| 四色在线精品免费观看| 国产精品免费小视频| 亚洲AⅤ无码一区二区三区在线| 亚洲精品成a人在线观看| 国产成人A亚洲精V品无码| 亚洲日韩乱码中文无码蜜桃臀网站| 在线亚洲精品福利网址导航| 国产国拍精品亚洲AV片 | 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | 亚洲第一成年免费网站| 亚洲av中文无码乱人伦在线观看| 国产成人亚洲综合在线| 一级毛片完整版免费播放一区| 99热在线日韩精品免费| 中文字幕亚洲免费无线观看日本| 国产又大又粗又长免费视频| 日韩精品免费电影| 亚洲精品一级无码鲁丝片| 亚洲人色婷婷成人网站在线观看| 亚洲AV无码一区二区三区系列| 亚洲免费在线观看视频| MM1313亚洲精品无码久久| 精品熟女少妇aⅴ免费久久| 久久久久免费看黄a级试看 | 黄色a三级三级三级免费看| 91成人免费观看在线观看|