每天資訊JavaEE——Servlet詳解(一)

菜單

JavaEE——Servlet詳解(一)

一、JavaEE簡介

1.什麼是 JavaEE

JavaEE(Java Enterprise Edition),Java 企業版,是一個用於企業級 web 開發平臺。最早 由 Sun 公司定製併發布,後由 Oracle 負責維護。在 JavaEE 平臺規範了在開發企業級 web 應 用中的技術標準。

在 JavaEE 平臺共包含了 13 個技術規範(隨著 JavaEE 版本的變化所包含的技術點的數量 會有增多)。它們分別是:JDBC、JNDI、EJB、RMI、Servlet、JSP、XML、JMS、Java IDL、JPA、 JTA、JavaMail 和 JAF。

2.JavaEE版本

JavaEE——Servlet詳解(一)

二、Servlet簡介

1.Servlet 介紹

Servlet 是 Server Applet 的簡稱,稱為服務端小程式,是 JavaEE 平臺下的技術標準,基 於 Java 語言編寫的服務端程式。 Web 容器或應用伺服器實現了 Servlet 標準所以 Servlet 需 要執行在 Web 容器或應用伺服器中。Servlet 主要功能在於能夠在伺服器中執行並生成資料。

Servlet技術特點:

Servlet使用單程序多執行緒方式執行。

JavaEE——Servlet詳解(一)

Servlet在應用程式中的位置:

JavaEE——Servlet詳解(一)

2.web開發歷史

CGI:

公共閘道器介面(Common Gateway Interface,CGI)是 Web 伺服器執行時外部程式的規範。

JavaEE——Servlet詳解(一)

CGI缺點:*

以程序方式執行,對每一個客戶端的請求都要啟動一個程序來執行程式,導致使用者數目 增加時,伺服器端資源被大量佔用。

*由於對作業系統和程序的不深刻理解,使得開發人員開發的 CGI 程式經常遇到莫名其妙 的錯誤。

*不同的 CGI 之間不能共享資源。

FastCGI:

FastCGI 是對 CGI 模式的一個改進,採用了 Pooling 技術,一定程度上改善了效能,但是 由於仍然是基於程序執行的所以並沒有從根本上解決問題。

JavaEE——Servlet詳解(一)

三、伺服器

1.JavaEE應用伺服器(JavaEE Application Server)

應用伺服器是 Java EE 規範的具體實現,可以執行/驅動基於 JavaEE 平臺開發的 web 項 目。絕大部分的應用伺服器都是付費產品。

常見的應用服務

:Weblogic(BEA Oracle 收費)、 Webshpere(IBM 收費)、 JBoss(RedHad 收費;4。0以前不收費)、Resin(Caucho 收費)、JRun(Macromedia 收費)、 Geronimo(Apache 免費)。

2.web容器(Web Server)

只實現了 JavaEE 平臺下部分技術標準,如 Servlet,Jsp,JNDI,JavaMail。Web 容器是開 源免費的。常見的有:Tomcat(Apache 開源免費)、Jetty(Jetty 開源免費)。

3.Tomcat的使用

Tomcat的使用在下面這篇文章裡從下載安裝到目錄結構再到啟動、關閉、配置、工作原理、架構、配置虛擬主機等都做了詳細的介紹:

WEB容器——Tomcat的使用

四、Servlet技術詳解

1.手動建立一個Servlet案例

在下面這篇文章裡詳細介紹了這個Servlet案例的建立過程:

建立第一個Servlet例項

2. Servlet繼承結構

JavaEE——Servlet詳解(一)

Servlet介面方法:

init(),建立 Servlet 物件後立即呼叫該方法完成其他初始化工作。

service(),處理客戶端請求,執行業務操作,利用響應物件響應客戶端請求。

destroy(),在銷燬 Servlet 物件之前呼叫該方法,釋放資源。

getServletConfig(),ServletConfig 是容器向 servlet 傳遞引數的載體。

getServletInfo(),獲取 servlet 相關資訊。

ServletConfig介面:

Servlet 執行期間,需要一些輔助資訊,這些資訊可以在 web。xml 檔案中,使用一個或多 個元素,進行配置。當 Tomcat 初始化一個 Servlet 時,會將該 Servlet 的配置資訊,封裝到 一個 ServletConfig 物件中,透過呼叫 init(ServletConfig config)方法,將 ServletConfig 對像傳遞給 Servlet。

GenericServlet類:

GenericServlet 是實現了 Servlet 介面的抽象類。在 GenericServlet 中進一步的定義了Servlet 介面的具體實現,其設計的目的是為了和應用層協議解耦,在 GenericServlet 中包含 一個 Service 抽象方法。我們也可以透過繼承 GenericServlet 並實現 Service 方法實現請求的 處 理 , 但 是 需 要 將 ServletReuqest 和 ServletResponse 轉 為 HttpServletRequest 和 HttpServletResponse。

HttpServlet類:

繼承自 GenericServlet。 針對於處理 HTTP 協議的請求所定製。在 HttpServlet 的 service() 方 法 中 已 經 把 ServletReuqest 和 ServletResponse 轉 為 HttpServletRequest 和 HttpServletResponse。 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要強 轉。實際開發中, 直接繼承 HttpServlet, 並根據請求方式複寫 doXxx() 方法即可。

3.Servlet的生命週期

Servlet 的生命週期是由容器管理的,分別經歷三各階段:

init():初始化

service():服務

destroy():銷燬

當客戶端瀏覽器第一次請求 Servlet 時,容器會例項化這個 Servlet,然後呼叫一次 init 方法,並在新的執行緒中執行 service 方法處理請求。service 方法執行完畢後容器不會銷燬這 個 Servlet 而是做快取處理,當客戶端瀏覽器再次請求這個 Servlet 時,容器會從快取中直接 找到這個 Servlet 物件,並再一次在新的執行緒中執行 Service 方法。當容器在銷燬 Servlet 之 前對呼叫一次 destroy 方法。

4.Servlet處理請求的原理

當瀏覽器基於 get 方式請求我們建立 Servlet 時,我們自定義的 Servlet 中的 doGet 方法會被執行。doGet 方法能夠被執行並處理 get 請求的原因是,容器在啟動時會解析 web 工程 中 WEB-INF 目錄中的 web。xml 檔案,在該檔案中我們配置了 Servlet 與 URI 的繫結,容器通 過對請求的解析可以獲取請求資源的 URI,然後找到與該 URI 繫結的 Servlet 並做例項化處理 (注意:只例項化一次,如果在快取中能夠找到這個 Servlet 就不會再做次例項化處理)。

在例項化時會使用 Servlet 介面型別作為引用型別的定義,並呼叫一次 init 方法,由於 HttpServlet 中重寫了該方法所以最終執行的是 HttpServlet 中 init 方法(HttpServlet 中的 Init 方法是一個空 的方法體),然後在新的執行緒中呼叫 service 方法。由於在 HttpServlet 中重寫了 Service 方法,所以最終執行的是 HttpServlet 中的 service 方法。

在 service 方法中透過 request。getMethod() 獲取到請求方式進行判斷如果是 Get 方式請求就執行 doGet 方法,如果是 POST 請求就執行 doPost 方法。如果是基於 GET 方式提交的,並且在我們自定義的 Servlet 中又重寫了 HttpServlet 中的 doGet 方法,那麼最終會根據 Java 的多型特性轉而執行我們自定義的 Servlet 中的 doGet 方法。

5 Servlet 的作用

*獲取使用者提交的資料

*獲取瀏覽器附加的資訊 、

*處理資料(訪問資料庫或呼叫介面)

*給瀏覽器產生一個響應

*在響應中新增附加資訊

6.在idea中開發Servlet

為了開發在效率,不能一直用記事本工具開發Servlet,因此在下面這篇文章裡介紹瞭如何使用idea開發Servlet。

在IDEA裡開發Servlet

7.在eclipse中開發Servlet

另外,在eclipse中開發Servlet與在idea中開發的目的是一樣的都是為了開發效率,用哪款軟體開發都可以,下面這篇文章介紹了用eclipse開發Servlet的詳細介紹。

在Eclipse中開發Servlet

8.HttpServletRequest物件

HttpServletRequest 物件代表客戶端瀏覽器的請求,當客戶端瀏覽器透過 HTTP 協議訪問伺服器時,HTTP請求中的所有資訊都會被tomcat所解析並封裝在這個物件中,透過這個物件提供的方法,可以獲得客戶端請求的所有資訊。

8.1獲取請求資訊

req。getRequestURL() 返回客戶端瀏覽器發出請求時的完整URL。

req。getRequestURI() 返回請求行中指定資源部分。

req。getRemoteAddr() 返回發出請求的客戶機的 IP 地址。

req。getLocalAddr() 返回 WEB 伺服器的 IP 地址。

req。getLocalPort() 返回 WEB 伺服器處理 Http 協議的聯結器所監聽的埠。

下面是對這些方法的測試:

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

8.2獲取請求資料

在 Servlet 獲取請求資料的方式

req。getParameter(“key”) 根據 key 獲取指定 value。

String str = req。getParameter(“key”);

獲取複選框(checkbox 元件)中的值

req。getParameterValues(“checkboxkey”)

獲取複選框(checkbox 元件)中的值,返回一個 String[]。

String[] userlikes = req。getParameterValues(“checkboxkey”);

獲取所有提交資料的 key

req。getParameterNames()

獲取請求中所有資料的 key,該方法返回一個列舉型別。

Enumeration parameterNames = req。getParameterNames();

使用 Map 結構獲取提交資料

req。getParameterMap()

獲取請求中所有的資料並存放到一個 Map 結構中,該方法返回一個 Map,其中 key 為 String 型別 value 為 String[]型別。

Map parameterMap = req。getParameterMap();

下面是獲取請求資料方法的測試:

首先,我們先建一個HTML頁面,這裡的HTML頁面是作為提交請求的頁面,這個頁面放在webcontent目錄下,但不要放在WEB-INF目錄下(程式碼中的action=“requestdata。do”是在web。xml裡裡設定的值):

JavaEE——Servlet詳解(一)

其次,我們在建立Servlet,程式碼如下:

JavaEE——Servlet詳解(一)

最後,配置web。xml,測試結果(測試時,要先在html頁面裡輸入資料後才可以看到獲取的結果):

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

8.3設定請求編碼

req。setCharacterEncoding(“utf-8”)

請求的資料包基於位元組在網路上傳輸,Tomcat 接收到請求的資料包後會將資料包中的位元組轉換為字元。在 Tomcat 中使用的是 ISO-8859-1 的單位元組編碼完成位元組與字元的轉換,所以資料中含有中文就會出現亂碼,可以透過 req。setCharacterEncoding(“utf-8”)方法來對提交的資料根據指定的編碼方式重新做編碼處理。

例:在上面測試中,如果出現中文,會出現亂碼現象,此時就需要在請求資料以前設定請求編碼(當然,頁面中還是會出現亂碼,此方法解決的是請求的亂碼問題;後面的響應部分會解決頁面中出現的亂碼問題):

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

8.4資源訪問方式

絕對路徑

絕對路徑訪問資源表示直接以”/”作為專案的 Content Path。該方式適用於以”/”作為專案的 Content Path。

相對路徑

相對路徑訪問資源表示會相對於專案的 Content Path 作為相對路徑。該方式適用於為項 目指定的具體的 Content Path。

8.5獲取請求頭資訊

方法一:req。getHeader(“headerKey”)

根據請求頭中的 key 獲取對應的 value。

String headerValue = req。getHeader(“headerKey”);

方法二:req。getHeaderNames()

獲取請求頭中所有的 key,該方法返回列舉型別。

Enumeration headerNames = req。getHeaderNames();

該方法返回的是列舉,在輸出時需要遍歷結果:

while(headerNames。hasMoreElements()){

String key=headerNames。nextElements();

String value=req。getHeader(key);

out。print(“key:”+key+“value:”+value);

}

該方法測試:

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

案例:

編寫一個 Servlet,如果瀏覽器的語言是 zh-CN,顯示“你好,聰明的中國人!”, 如果瀏覽器的語言設定為 en-US,那麼則顯示“Hello,American”。

程式碼如下(用來判斷瀏覽器語言的key值是根據上面方法二測試的結果得出):

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

JavaEE——Servlet詳解(一)

8.6HttpServletRequest 物件的生命週期

當有請求到達 Tomcat 時,Tomcat 會建立 HttpServletRequest 物件,並將該物件透過引數 的方式傳遞到我們 Servlet 的方法中,當處理請求處理完畢併產生響應後該物件生命週期結束。