JavaWEB基礎 -- Servlet

修改原文傳送地址,原文寫的內容比較優秀,不過鑑於排版各方面問題對原文內容進行一些修改與重排版。大家有興趣可以查看原文作者的文章

一:概述與結構

現在很多做JavaWEB開發的攻城獅恐怕都對Servlet懵懵懂懂,MVC框架一頓操作猛如虎,隨便問一下Servlet慫如狗的人不在少數。Servlet究其根本就是Java中用於和客戶端交互達到數據瀏覽與修改目的。首先具備這樣功能的Servlet不少,祖宗都是Servlet接口,也就是正常的子類對父類的擴展,所以個人不是很認可網絡流傳的狹義與廣義的說法。別說了,都是Servlet就完事兒了
在這裏插入圖片描述

二:Servlet與容器

在這裏插入圖片描述
其實有人看到這裏是不太清楚WEB容器與Servlet,所以這裏提一下容器與Servlet是怎樣的愛恨情仇。也可以說一圖描述Servlet工作模型

三:祖宗接口Servlet

3.1 方法功能介紹

不多BB,既然是祖宗那就定義完成WEB請求處理到返回的基本功能就行,所以Servlet接口提供如圖幾個重寫方法,具體含義如下:

  • init:Servlet實例化依賴的方法,該方法在整個生命週期中只能被調用一次,生命畢竟只有一次。傳入的參數就是實例化Servlet對象時需要的一些數據
  • service:請求來了得處理呀,處理的邏輯就寫在service方法即可
  • destroy:當你老了,容器停了。destory方法就是最後的歸宿,銷燬
  • getServletInfo:返回一段Servlet的描述,有興趣可以調用方法打印出來看看
  • getServletConfig:返回的就是init初始化方法用到的ServletConfig對象

在這裏插入圖片描述

3.2 配置使用

首先需要在WEB容器的web.xml中配置好Servlet,需要兩部分的內容

  • <servlet>:定義Servlet對象由WEB容器進行加載
  • <servlet–mapping>:定義Servlet匹配處理的請求
    在這裏插入圖片描述
    在這裏插入圖片描述

四:請求封裝接口ServletRequest

發起一次請求包含許多信息數據,除了參數傳遞外可能重要的就是編碼類型、協議類型、請求端的IP地址端口等信息。ServletRequest接口定義許多相關方法,方法過多下圖展示幾種常用方法。經過這裏的IP其實並不能拿到客戶端真實的IP地址,真實IP在後面講解。有關characterEncoding與ContentType也是很多人疑惑的地方,會有單獨的文章講解
在這裏插入圖片描述

五:響應封裝接口ServletResponse

請求處理完畢總得對客戶端有個交代,返回數據信息還是什麼操作就依靠ServletResponse完成。所以這個接口與ServletRequest接口有比較鮮明的對比就是方法大部分都是set賦值操作,get獲取的就是一些流操作。除了Writer流之外還有OutPutStream單字節流,關於Java的I/O流知識自行查看相關文章
在這裏插入圖片描述

六:初始化信息封裝接口ServletConfig

web.xml配置文件中可以配置一些Servlet初始化的信息,比如名字以及一些默認參數等信息。這些信息則封裝到ServletConfig中然後init初始化時就會根據這個對象進行系列的初始化。下面演示一下web.xml中隨便配置點默認參數後再init()初始化方法中獲取打印
在這裏插入圖片描述
在這裏插入圖片描述

七:WEB項目容器與ServletContext

7.1 Tomcat容器

其餘部分都不看,這裏主要就是想說這個Context容器。一個Tomcat容器可以部署多個WEB項目,每個WEB項目就對應唯一的Context容器,包含了運行時的一些數據信息存儲等
在這裏插入圖片描述

7.2 多個Servlet

Servlet當然可以有多個,只需要在web.xml配置文件中配置即可,每一個Servlet可能都會有自己匹配的方法後進行不同的邏輯處理等。但是如果這些Servlet想要留下點什麼怎麼保留?這時候就可以通過ServletContext容器
在這裏插入圖片描述

7.3 ServletContext使用

通過前面你知道init()初始化參數會傳遞一個ServletConfig對象,這個對象就可以獲取到ServletContext容器。所以初始化的時候就把這個ServletConfig配置對象交給屬性servletConfig維護,然後在getServletConfig()返回
在這裏插入圖片描述
在這裏插入圖片描述
頁面首先請求FirstServlet然後再請求TwoServlet就可以獲取到容器中存儲的屬性對象

在這裏插入圖片描述

八:初級抽象GenericServlet

8.1 繼承結構

前面一直操作Servlet接口然後提供實現類,這屬於騷操作,太累了有點。所以需要提供一個解放程序員的類,那就是抽象類GenericServlet。該抽象類實現了Servlet與ServletConfig接口,實現了比如前面講到的使用屬性維護ServletConfig對象,方便操作容器。然後還提供ServletConfig裏面的參數、Servlet名字以及ServletContext等。當然唯一沒有實現的就是處理邏輯的service(),有興趣可以看看這個抽象類的源碼
在這裏插入圖片描述

8.2 init初始化

看了源碼都會奇怪爲什麼在GenericServlet中要新增一個無參的init()方法,是不是會感覺特別沒用?仔細看看別人做的什麼操作,正常重寫帶有ServletConfig參數的初始化方法後調用了這個方法,也就是GenericServlet的子類你重寫初始化方法就給我重寫這個無參的,有參的別動。必須要保證ServletConfig對象屬性不爲空的引用,別給瞎寫破壞了
在這裏插入圖片描述
在這裏插入圖片描述

九:深層抽象HttpServlet

GenericServlet已經做出了優秀的成績,但是對於Http請求來說還差那麼點意思。所以呀它的子類HttpServlet橫空出世

  • 強轉ServletRequest與ServletResponse
  • 分化處理GTE、POST等請求

首先看HttpServlet重寫的service()方法,直接把參數的ServletRequest與ServletyResponse強轉爲其子接口HttpServletRequest、HttpServletResponse。強轉不報錯是因爲Servlet容器傳給service方法的參數就是這倆,只不過經歷了向上轉型後又強轉回來
在這裏插入圖片描述
再來看一下另外一個被調用的service()在幹嘛,如下圖可以很清晰看到就是在根據請求的方式然後調用不同的方法進行處理,也就是分化處理不同類型請求。所以在繼承實現HttpServlet抽象類的時候不需要覆蓋service(),只需要重寫doGet()、doPost()等請求方法即可
在這裏插入圖片描述
使用測試一下還是比較容易的,如下圖所示。改下寫前面使用的TwoServlet後瀏覽器發起請求返回
在這裏插入圖片描述
在這裏插入圖片描述

十:Http環境請求接口HttpServletRequest

HTTP請求分爲請求行、請求頭、請求體,HttpServletRequest自然可以分門別類的獲取這三部分信息內容。至於HTTP請求的詳細信息移步通信信息分類

10.1 請求行信息

請求行信息中主要就是包括請求方式、WEB應用名稱、跟在URL後面的參數(GET請求)。針對這個WEB應用名稱其實就是配置WEB容器的時候設置的名稱,這個名稱也就是請求的根路徑,如圖二所示
在這裏插入圖片描述
在這裏插入圖片描述

10.2 請求頭信息

請求頭也就是key-value形式的map數據,可以根據key獲取到對應的value。這個與ServletConfig獲取到web.xml配置文件中的信息類似
在這裏插入圖片描述

10.3 請求體信息

請求體就是封裝POST請求數據的地方,並不會直接暴露在URL路徑下,所以一般做登錄提交的時候都會發起POST請求。需要說明一點的就是接下來的方法也可以適用於GET請求獲取URL路徑後跟着的參數。在這總結一下這種key-value的操作:

  • ServletConfig中獲取web.xml配置的參數init
  • HttpServletRequest中可以獲取請求頭header
  • HttpServletRequest中可以獲取請求體parameter
    在這裏插入圖片描述

十一:Http環境響應接口HttpServletResponse

HttpServletResponse接口繼承自ServletResponse接口,主要是做一些HTTP請求響應的工作。HTTP請求具備請求行、請求頭、請求體。自然HTTP響應也具備這三塊內容,所以在HttpServletResponse接口中提供三者的設置方法
在這裏插入圖片描述
在這裏插入圖片描述

十二:亂碼問題

servlet默認的編碼以及解碼字符集採用iso8859-1,這個字符集中是沒有中文的。所以會造成最後的亂碼現象,這時候就需要設定Servlet編碼以及解碼的字符集

12.1 請求參數帶中文

當服務端接收到請求的時候需要使用到請求參數,請求參數的編碼字符集可以通過ServletRequest對象的setCharacterEncoding()進行設置,設置爲與項目編碼一致的字符集,達到使用請求參數不亂碼的效果
在這裏插入圖片描述

12.2 響應帶中文

通過服務端系列邏輯處理後需要給客戶端瀏覽器返回信息難免會帶有中文數據,這時候服務端需要做的工作就是將數據進行編碼並且告訴瀏覽器解碼的字符集類型
在這裏插入圖片描述
除了這兩個步驟之外還有沒有一步到位的方法?別說還真有,一個方法指定服務端編碼格式與瀏覽器客戶端解碼格式
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章