Servlet01
官方api檔案:https://tomcat.apache.org/tomcat-8.0-doc/servletapi/index.html
Servlet和Tomcat的關系:一句話,Tomcat支持Servlet
Servlet是跟Tomcat關聯在一起的,換而言之,Tomcat是哪個版本,就對應哪個版本的Servlet
1.為什么需要Servlet?
需求:請用你現有的html,css,javascript,開發網站,比如可以讓用戶留言/購物/支付,你能搞定嗎?
這就需要引入我們的動態網頁(能和用戶互動)技術===>Servlet
我們對之前的JavaWeb技術體系圖進一步地細化:

Tomcat的web服務拿到一個請求后:
-
如果web服務發現是該請求是和java相關的,或者說是一個Servlet(動態請求,比如說可能會去操作資料庫),那么Tomcat會去尋找Servlet,Servlet又去呼叫java程式,進行資料庫操作
-
如果Tomcat的web服務發現請求的是一個靜態資源,比如html,圖片等,就直接拿到該資源,然后回傳,不會和java程式或者資料庫發生關系
-
因此我們說Tomcat其實是有兩個功能的:一是充當Servlet的容器;二是充當普通的web服務
-
只支撐靜態資源回傳的還有apache,如果是一個靜態資源的網站,不需要和資料庫進行互動,其實完全可以使用Apache來作為web服務,或者只使用一個Nginx就可以了
2.什么是Servlet?
-
什么是Servlet
Servlet在開發動態WEB工程中得到了廣泛地應用,掌握好Servlet非常重要,Servlet是SpringMVC的基礎
-
Servlet(java服務器小程式),它的特點有:
-
它是由服務器呼叫和執行的
即由tomcat決議和執行的
-
它是用java語言撰寫的,本質就是Java類
-
它是按照Servlet規范開發的(介面),Servlet本質就是一套介面規范
除了Tomcat可以去決議Servlet,weblogic也可以支持 Servlet,即只要按照規范去開發介面,就可以支持Servlet,類似于jdbc的介面規范
-
功能強大,幾乎完成所有的網站功能
-
3.Servlet基本使用
3.1Servlet開發方式說明
- Servlet3.0前使用web.xml,Servlet3.0版本以后(包括3.0)支持注解,同時支持web.xml配置
- 如何查看Servlet版本
- Servlet的講解只是為了知道Servlet的使用原理(原生的Servlet在專案中使用很少)
- 不管使用哪種方式,本質都一樣
3.2快速入門-手動開發Servlet
例子
需求說明:
- 開發一個HelloServlet
- 當瀏覽器訪問
http://localhost:8080/web應用名/helloServlet時,后臺輸出“hi HelloServlet”
思路:
-
撰寫類HelloServlet去實作Servlet介面
-
實作service方法,處理請求,并回應資料
-
在web.xml中去配置Servlet程式的訪問地址
-
首先創建web工程,配置好Tomcat

-
添加servlet-api.jar(在你安裝的tomcat/lib下)到工程,因為servlet.jar不是jdk自帶的,要引入才可以使用
在idea專案的web/WEB-INF下創建一個lib目錄,將servlet-api.jar拷貝進去,然后右擊jar包,點擊add as library,在彈出的視窗中點擊ok即可
-
在src包下面創建HelloServlet.java,并實作Servlet介面
package com.li.servlet; import javax.servlet.*; import java.io.IOException; /** * 1.開發一個servlet,需要實作Servlet介面 * 2.實作Servlet介面的方法:一共有5個 */ public class HelloServlet implements Servlet { /** * 1.初始化 Servlet * 2.當創建HelloServlet實體時,會呼叫init方法 * 3.該方法只會被呼叫一次 * * @param servletConfig * @throws ServletException */ @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("init() 被呼叫"); } /** * 回傳ServletConfig物件 也就是回傳Servlet的配置 * * @return */ @Override public ServletConfig getServletConfig() { return null; } /** * 1.service方法處理瀏覽器的請求(包括get/post) * 2.當瀏覽器每次請求Servlet時,就會呼叫一次server方法 * 3.當Tomcat呼叫該方法時,會把http請求的資料封裝成 實作了ServletRequest介面 的request物件 * 4.通過servletRequest物件,就可以得到用戶提交的資料 * 5.servletResponse物件可以用于回傳資料給Tomcat-->瀏覽器 * * @param servletRequest * @param servletResponse * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("hi HelloServlet~"); } /** * 回傳servlet的資訊,使用較少 * * @return */ @Override public String getServletInfo() { return null; } /** * 1.該方法是在servlet被銷毀時,被tomcat呼叫 * 2.只會呼叫一次 */ @Override public void destroy() { } } -
實作了介面之后,在web.xml配置HelloServlet,即給HelloServlet提供對外的訪問地址
目的是為了告訴Tomcat服務器,HelloServlet在哪里
<?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--web.xml檔案主要用來配置該web應用使用到的Servlet--> <!--配置HelloServlet--> <!--解讀: 1.servlet-name:給Servlet取名(任意),該名字唯一 2.servlet-class:Servlet的類的全路徑,Tomcat在反射生成該Servlet類實體時需要使用 3.servlet-mapping里的servlet-name要和上面的servlet-name保持一致 4.url-pattern:這個就是該Servlet訪問的url的配置(路徑) 5.這時我們應該這樣訪問Servlet:http://localhost:8080/web應用名/helloServlet 6.url-pattern的取名也是隨意的(注意加上斜杠) --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.li.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/helloServlet</url-pattern> </servlet-mapping> </web-app>設定 快捷鍵ctrl+/ 可以在當前位置注釋,而不是在行
-
訪問HelloServlet(記得要reploy或者restart)
可以自己配置快捷鍵啟動
瀏覽器訪問:
后臺輸出:可以看到init方法只呼叫了一次,而每次訪問都會呼叫server方法
4.瀏覽器呼叫Servlet流程分析
注意這里的第幾次請求是值對于Tomcat而言,并不在乎是哪個瀏覽器
- 如果是第一次請求(Tomcat)
-
首先查詢web.xml檔案
-
看看請求的資源/helloServlet在web.xml有沒有配置url-pattern
-
如果找到url-pattern,就會得到對應的servlet-name:HelloServlet
-
Tomcat維護了一個大的HashMap<id,Servlet>,查詢該HashMap,看看有沒有這個Servlet實體
-
如果沒有查詢到該servlet-name對應的id,即沒有這個Servlet實體
-
就根據servlet-name去得到servlet-class:類的全路徑
-
使用反射技術,將servlet實體化(同時呼叫init方法),并將該實體放入到Tomcat維護的HashMap<id,Servlet>中
- 如果是第二次及其之后請求(Tomcat)
-
首先查詢web.xml檔案
-
看看請求的資源/helloServlet在web.xml有沒有配置url-pattern
-
如果找到url-pattern,就會得到對應的servlet-name:HelloServlet
-
Tomcat維護了一個大的HashMap<id,Servlet>,查詢該HashMap,看看有沒有這個Servlet實體
-
如果查詢到,就直接呼叫該Servlet的service方法
-
結果處理
-
前面說到Servlet是單例的,現在來證明:
在實作的Servlet類HelloServlet中增加一個count屬性
在service方法中,增加陳述句
count++;并將其輸出,如果每次輸出的count是累加的,就說明每一次請求使用的都是同一個Servlet實體
使用瀏覽器訪問:
后臺輸出:(在切換不同的瀏覽器訪問后,count的值仍是累加的)
5.Servlet生命周期
- 主要有三個方法
- init() 初始化階段
- service() 處理瀏覽器請求階段
- destroy() 終止階段
-
示意圖
5.1初始化階段-init()
Servlet容器(比如Tomcat)加載Servlet,加載完之后,Servlet容器會創建一個Servlet實體并呼叫init()方法,init方法只會呼叫一次,Servlet容器在下面的情況裝載Servlet
-
Servlet容器(如Tomcat)啟動時自動裝載某些servlet,實作這個需要在web.xml檔案中添加
<load-on-startup>1</load-on-startup> <!--1表示裝載的順序,比如在--> -
在Servlet容器(如Tomcat)啟動后,瀏覽器首次向Servlet發送請求
-
Servlet重新裝載時(比如tomcat進行redeploy),瀏覽器再向Servlet發送請求的第1次
redeploy會銷毀所有的Servlet實體
例子1:<load-on-startup>1</load-on-startup>
在web.xml檔案中添加<load-on-startup>1</load-on-startup>之后,重新啟動tomcat,可以看到,在沒有瀏覽器發送請求的情況下,呼叫了init方法,這說明該Servlet已經被裝載
例子2:Servlet重新裝載時(比如tomcat進行redeploy),瀏覽器再向Servlet發送請求的第1次會裝載Servlet
后臺顯示狀況:

說明redeploy后Servlet實體被銷毀了,當瀏覽器再次請求時,Tomcat會重新裝載Servlet,因此init方法再次被呼叫
5.2處理瀏覽器請求階段-service()
- 每收到一個http請求,服務器就會產生一個新的執行緒去處理
- 創建一個用于封裝HTTP請求訊息的ServletRequest物件和一個代表HTTP回應訊息的ServletResponse物件
- 然后呼叫Servlet的service()方法并將請求和回應物件作為引數傳遞進去
例子1:驗證是否每收到一個http請求,服務器就會產生一個新的執行緒處理
在service方法中輸出當前執行緒的id
瀏覽器請求Servlet時后臺的輸出:
5.3終止階段-destroy()
當web應用被終止,或者Servlet容器終止運行,或者Servlet類重新裝載時,會呼叫destroy方法(很少使用)
比如重啟Tomcat,或者redeploy web應用
例子
在destroy方法中輸出提示
重啟Tomcat,在瀏覽器訪問Servlet(讓Servlet類加載),然后選擇redeploy,可以看得destroy方法被呼叫了:
在瀏覽器再次請求Servlet,這次直接點擊停止Tomcat服務,可以看到destroy方法也被呼叫了
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/528056.html
標籤:其他
上一篇:JAVA的File物件
