初学Java Web(3)——第一个Servlet
這學(xué)期 Java Web 課程的第一節(jié)課就簡短復(fù)習(xí)了一下 Java 的一些基礎(chǔ)知識,所以覺得 Java 的基礎(chǔ)知識還是很重要的,但當(dāng)我想要去寫一篇 Java 回顧的文章的時候發(fā)現(xiàn)很難,因為坑實在太多了(一個頭,兩個大),只能另外找一些時間去寫順便鞏固鞏固自己的基礎(chǔ)。
——【1. 什么是 Servlet 】——
學(xué)習(xí)一個東西就要先去了解它是什么東西。
Servlet 取自兩個單詞:Server、Applet (很符合 sun 公司的命名特點), Java Servlet 的簡稱,其實質(zhì)就是運行在 Web 應(yīng)用服務(wù)器上的 Java 程序,與普通 Java 程序不同,它是位于 Web 服務(wù)器內(nèi)部的服務(wù)器端的 Java 應(yīng)用程序,可以對 Web 瀏覽器或其他 HTTP 客戶端程序發(fā)送的請求進(jìn)行處理。
狹義的Servlet是指Java語言實現(xiàn)的一個接口,廣義的Servlet是指任何實現(xiàn)了這個Servlet接口的類,一般情況下,人們將Servlet理解為后者。Servlet運行于支持Java的應(yīng)用服務(wù)器中。從原理上講,Servlet可以響應(yīng)任何類型的請求,但絕大多數(shù)情況下Servlet只用來擴展基于HTTP協(xié)議的Web服務(wù)器。
實際上,Servlet 就像是一個規(guī)范,想象一下我們的 USB 接口,它不僅約束了U盤的大小和形狀,同樣也約束了電腦的插槽,Servlet 也是如此,它不僅約束了服務(wù)器端如何實現(xiàn)規(guī)范,也約束著 Java Web 項目的結(jié)構(gòu),為什么這樣說,我們下面再來講,編寫一個 Servlet 其實就是按照 Servlet 規(guī)范編寫一個 Java 類。
——【2. Servlet 與 Servlet 容器 】——
Servlet 對象與普通的 Java 對象不同,它可以處理 Web 瀏覽器或其他 HTTP 客戶端程序發(fā)送的 HTTP 請求,但前提是把 Servlet 對象布置到 Servlet 容器中,也就是說,其運行需要 Servlet 容器的支持。
Servlet 容器也叫做 Servlet 引擎,是 Web 服務(wù)器或應(yīng)用程序服務(wù)器的一部分,用于在發(fā)送的請求和響應(yīng)之上提供網(wǎng)絡(luò)服務(wù),解碼基于 MIME 的請求,格式化基于 MIME 的響應(yīng)。Servlet 沒有 main 方法,不能獨立運行,它必須被部署到 Servlet 容器中,由容器來實例化和調(diào)用 Servlet 的方法(如 doGet() 和 doPost() 方法),Servlet 容器在 Servlet 的生命周期內(nèi)包容和管理 Servlet 。在 JSP 技術(shù) 推出后,管理和運行 Servlet / JSP 的容器也稱為 Web 容器。
有了 Servlet 之后,用戶通過單擊某個鏈接或者直接在瀏覽器的地址欄中輸入 URL 來訪問 Servlet ,Web 服務(wù)器接收到該請求后,并不是將請求直接交給 Servlet ,而是交給 Servlet 容器。Servlet 容器實例化 Servlet ,調(diào)用 Servlet 的一個特定方法對請求進(jìn)行處理, 并產(chǎn)生一個響應(yīng)。這個響應(yīng)由 Servlet 容器返回給 Web 服務(wù)器,Web 服務(wù)器包裝這個響應(yīng),以 HTTP 響應(yīng)的形式發(fā)送給 Web 瀏覽器。
Servlet 容器能提供什么?
上面我們知道了需要由 Servlet 容器來管理和運行 Servlet ,但是為什么要這樣做呢?使用 Servlet 容器的原因有:
Servlet 生命周期
通常情況下,Servlet 容器也就是指 Web 容器,如 Tomcat、Jboss、Resin、Weblogic 等,它們對 Servlet 進(jìn)行控制。當(dāng)一個客戶端發(fā)送 HTTP 請求時,由容器加載 Servlet 對其進(jìn)行處理并做出響應(yīng)。在 Web 容器中,Servlet 主要經(jīng)歷 4 個階段,如下圖:
Servlet 與 Web 容器的關(guān)系是非常密切的,在 Web 容器中 Servlet 主要經(jīng)歷了 4 個階段,這 4 個階段實質(zhì)是 Servlet 的生命周期,由容器進(jìn)行管理。
(1)在 Web 容器啟動或者客戶機第一次請求服務(wù)時,容器將加載 Servlet 類并將其放入到 Servlet 實例池。
(2)當(dāng) Servlet 實例化后,容器將調(diào)用 Servlet 對象的 init() 方法完成 Servlet 的初始化操作,主要是為了讓 Servlet 在處理請求之前做一些初始化工作。
(3)容器通過 Servlet 的 service() 方法處理客戶端請求。在 Service() 方法中,Servlet 實例根據(jù)不同的 HTTP 請求類型作出不同處理,并在處理之后作出相應(yīng)的響應(yīng)。
(4)在 Web 容器關(guān)閉時,容器調(diào)用 Servlet 對象的 destroy() 方法對資源進(jìn)行釋放。在調(diào)用此方法后,Servlet 對象將被垃圾回收器回收。
——【3. 第一個 Servlet 】——
① 搭建 Java Web 項目
在 WEB-INF 文件中添加 Tomcat 根目錄下 conf 文件夾中的 web.xml 文件;(只保留根元素,就像下面這樣)
```
?
?
```把當(dāng)前項目的 classpath 路徑改成 webapp/WEB-INF 下的 classes 中。
② 編寫 Servlet
為該項目增加Servlet的支持.
1.1. 把Tomcat根/lib中servlet-api.jar文件拷貝到項目下WEB-INF下的lib中
1.2. 在項目中選擇servlet-api.jar,鼠標(biāo)右鍵,build path-->add to build path
開發(fā)Servlet程序:
2.1:定義一個類HelloServlet,并讓該類去實現(xiàn)javax.servlet.Servlet接口;
2.2:實現(xiàn)Servlet接口中的init,service,destory等方法.
注意:若生成方法中的參數(shù)是 arg0 或則 arg1 等格式的,原因是還沒有關(guān)聯(lián)源代碼的問題:?關(guān)聯(lián)上 tomcat src 文件即可
③ 配置 Servlet
上面編寫好的 HelloServlet 類僅僅是一個普通的實現(xiàn)類而已,而現(xiàn)在我想要它運行在我自己的 Tomcat 服務(wù)器中,所以應(yīng)該通知 Tomcat 服務(wù)器來管理我的 HelloServlet 類,具體的做法如下:
在根元素web-app中創(chuàng)建一個新的元素節(jié)點:servlet-mapping(Servlet 的映射)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>lt.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping></web-app>web.xml 提供路徑和servlet映射關(guān)系,這意思是把/hello這個路徑,映射到 HelloServlet 這個類上,需要注意的是:< servlet> 標(biāo)簽下的 < servlet-name>與 < servlet-mapping> 標(biāo)簽下的 < servlet-name> 必須一樣(因為標(biāo)簽被編輯器識別故<后加了一個空格)
配置 Tomcat 服務(wù)器:
4.1. 修改默認(rèn)端口為 80 端口:
首先進(jìn)入到 Tomcat 服務(wù)器的根路徑下找到 conf 文件夾下的 server.xml 文件,默認(rèn)是在第 70 行,找到 Connector 元素的 port 屬性,修改為 80 ,重啟 Tomcat 即可。
Tomcat 的默認(rèn)端口為8080,而 HTTP 協(xié)議的默認(rèn)端口是 80,配置 80 端口的好處在于,我們平時輸入的類似于 http://baidu.com 其實是默認(rèn)省略了寫 80端口的,它其實等價于:http://baidu.com:80/ ,所以以后我們就不用再寫冒號直接輸入 locahost 就能進(jìn)入到 Tomcat 的配置頁面了。
4.2 部署 Java 項目(告訴 Tomcat 服務(wù)器來管理我們的項目):
這里直接引用 how2j.cn 的教程啦:
所以加上<Context path="" docBase="F:\\Projects\\JavaProject\\HelloServlet\\webapp" />這一句重啟 Tomcat 服務(wù)器
在瀏覽器中輸入 localhost/hello,回車,即可在 Tomcat 服務(wù)器上看到相關(guān)信息,至此第一個 Servlet 就編寫成功了
——【4. Servlet 請求過程】——
學(xué)習(xí) Servlet 技術(shù),就需要有一個 Servlet 運行環(huán)境,也就是需要有一個 Servlet 容器,如這里使用的【Tomcat】。
Tomcat 服務(wù)器接受客戶請求并做出響應(yīng)的過程如下(以上面搭建的項目為例):
① 打開瀏覽器發(fā)起請求:http://localhost:80/hello/index.html (假設(shè)有一個 index.html 文件)
② 服務(wù)器接收到請求后處理請求:
htpp:所使用的協(xié)議
localhost:ip地址,確定訪問的主機
80:端口號
hello:上下文路徑,確定訪問項目的根路徑
index.html:確定訪問項目中的具體哪一個資源
③ 根據(jù) hello 去 tomcat/conf/server.xml 文件中找到相關(guān)配置文件,根據(jù)上下文路徑找到項目的根路徑:
<Context path="" docBase="F:\\Projects\\JavaProject\\HelloServlet\\webapp" />
如果找不到根路徑(因為這里默認(rèn)上下文路徑為空),返回 404
④ 根據(jù)資源名稱去項目中的 web.xml 文件中找到相關(guān)的配置,找到配置中的<url-pattern>
如果找不到 hello 的資源名稱,則返回 404
⑤ 根據(jù)資源名稱找到 Servlet 的全限定名,如果找不到則在啟動服務(wù)器的時候報錯
java.lang.IllegalArgumentException: Servlet mapping specifies an unknown servlet name HelloServlet
⑥ 根據(jù)找到的全限定名創(chuàng)建對象,在創(chuàng)建對象之前需要判斷是否是第一次請求,使用 Tomcat 中使用 Servlet 實例緩存池來實現(xiàn),若是第一次則調(diào)用對象的 init 方法。
⑦ 創(chuàng)建 req,resp 對象,執(zhí)行 service 方法;
⑧ 使用 resp 對象給瀏覽器響應(yīng)信息。
發(fā)現(xiàn)一邊學(xué)一邊寫起來太麻煩了,一方面是因為自己的水平,另一方面是覺得這樣太費時間了,也要開始找實習(xí)了,所以時間有些寶貴,可能這不會作為一個連續(xù)的系列,反而是一些學(xué)習(xí)的分享和感悟,emmm....事實上,Servlet也還有好多東西,包括最新支持注解方式配置等....
參考資料:
《Java Web程序設(shè)計 慕課版——明日科技》
how2j.cn
理解Servlet和Servlet容器、Web服務(wù)器等概念
***
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz
歡
總結(jié)
以上是生活随笔為你收集整理的初学Java Web(3)——第一个Servlet的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初学Java Web(1)——Web概述
- 下一篇: java美元兑换,(Java实现) 美元