Servlet主要相關類核心類 容器調用的過程淺析 servlet解讀 怎么調用 Servlet是什么 工作機制


 

WEB簡介

 
Web項目 是 B/S結構 瀏覽器/服務器模式的
瀏覽器發起請求,服務器作出響應
 
請求的發起和響應使用HTTP協議進行通訊
所謂協議也就是一種固定格式
 
而Socket是應用層與傳輸層的一層編程接口,屏蔽了傳輸層的細節
所以Web項目也就是通過Socket發送HTTP請求和響應的過程
只不過請求是瀏覽器發出來的 響應是服務器發出來的
 
針對於JavaWeb項目,動態響應則是Servlet容器通過調用Servlet進行響應
應用程序員所要做的也就只是編寫符合Servlet規范的Servlet
 
一個基本的 請求--響應 調用過程
 
 
 
Servlet規范約定了Servlet容器與Servlet的工作過程以及工作細節
規范的概念 反映到代碼里也就是面向接口的編程
 

Servlet API主要由兩個包組成: javax.servlet和javax.servlet.http
 
在javax.servlet包中定義了Servlet接口及相關的通用接口和類;
在javax.servlet.http包中主要定義了與HTTP協議相關的HttpServlet類,HttpServletRequest接口和HttpServletResponse接口;
 

Servlet

 
Servlet是基於Java 技術的web組件,容器托管的,用於生成動態內容。
平台無關的,協議無關的
基於web的訪問模式必然是有   /請求/處理/響應/      的過程
 
Servlet是頂級接口,表示服務端的運行的程序
GenericServlet抽象類為Servlet接口提供了通用實現,想要實現Servlet只需要繼承GenericServlet即可,它與任何網絡應用層協議無關。
 
HttpServlet是針對於HTTP請求的Servlet實現
同理HttpRequest HttpResponse 也是針對HTTP協議的
 
為什么要繞這么多層,是因為Servlet不針對任何具體的協議,是協議獨立的
雖然web應用人員基本上都是在使用HTTPServlet但是並不代表他就只是http協議
 
Servlet接口中的:
public void init(ServletConfig config)
public void service(ServletRequest req, ServletResponse res)
public void destroy();
三個方法是生命周期方法,由容器負責調用
 

創建servlet的三種方式

  1. 定一個類實現javax.servlet.Servlet接口
  2. 定義一個類繼承javax.servet.GenericServlet類
  3. 定義一個類繼承javax.servlet.http.HttpServlet類   web應用我們自然基本上都是繼承HttpServlet
Servlet的生命周期 由一套定義良好的生命周期規則來約束管理
其中定義了Servlet如何被加載實例化和初始化,處理客戶端請求,以及何時結束服務
生命周期方法有:
       void init(ServletConfig);
       void service(ServletRequest,ServletResponse);
       void destroy();
 
1. 服務器會在Servlet第一次被訪問時創建Servlet,或者是在服務器啟動時創建Servlet。
如果服務器啟動時就創建Servlet,那么還需要在web.xml文件中配置。也就是說默認情況下,Servlet是在第一次被訪問時由服務器創建的
2. 而且一個Servlet類型,服務器只創建一個實例對象,當我們再次訪問,不在創建 而是直接使用上次創建的實例。
3. 在Servlet被創建后,服務器會馬上調用Servlet的void init(ServletConfig)方法。請記住, Servlet出生后馬上就會調用init()方法,而且一個Servlet的一生這個方法只會被調用一次
Servlet服務
當服務器每次接收到請求時,都會去調用Servlet的service()方法來處理請求。
服務器接收到一次請求,就會調用service() 方法一次,所以service()方法是會被調用多次的。
正因為如此,所以我們才需要把處理請求的代碼寫到service()方法中
Servlet銷毀
Servlet是不會輕易被銷毀的,通常都是在服務器關閉時Servlet才會銷毀!
在服務器被關閉時,服務器會去銷毀Servlet,在銷毀Servlet之前服務器會先去調用Servlet的destroy()方法,
我們可以把例如對某些資源的釋放等代碼放到destroy()方法中。
 
小技巧:
GenericServlet實現了 init(ServletConfig config)方法
並且自定義了一個init()方法 方法內容為空
我們知道GenericServlet是Servlet的抽象實現類,完成了Servlet的基本實現
如果你想要實現自己的Servlet,一般情況下不至於去直接使用實現Servlet
所以都會繼承GenericServlet
在繼承的時候如果你還想要有自己的個性化特殊的初始化方法,就可以覆蓋這個空的無參數的init()
    public void init(ServletConfig config) throws ServletException {         this.config = config;         this.init();     }
 
    public void init() throws ServletException {     }
 
 

 

請求

 
 
ServletRequest:Servlet.service() 方法的參數,它表示請求對象,它封裝了所有與請求相關的數據,它是由服務器創建的
 
 
常用方法備注:
getContentLength() —— 返回請求正文的長度,如果請求正文的長度未知,則返回-1;
getContentType() —— 獲得請求正文的MIME類型,如果請求正文的類型為止,則返回null;
getInputStream() —— 返回用於讀取請求正文的輸入流;
getLocalAddr() —— 返回服務端的IP地址;
getLocalName() —— 返回服務端的主機名;
getLocalPort() —— 返回服務端的端口號;
getParameters() —— 根據給定的請求參數名,返回來自客戶請求中的匹配的請求參數值;
getProtocal() —— 返回客戶端與服務器端通信所用的協議名稱及版本號;
getReader() —— 返回用於讀取字符串形式的請求正文的BufferReader對象;
getRemoteAddr() —— 返回客戶端的IP地址
getRemoteHost() —— 返回客戶端的主機名
getRemotePort() —— 返回客戶端的端口號
 
HttpServletRequest接口提供了用於讀取HTTP請求中的相關信息的方法:
getContextPath() —— 返回客戶端請求方法的Web應用的URL入口,例如,如果客戶端訪問的URL為http://localhost:8080/myApp/index,那么該方法返回“/myApp”;
getCookies() —— 返回HTTP請求中的所有Cookie;
getHeader(String name) —— 返回HTTP請求頭部的特定項;
getHeaderName() —— 返回一個Enumeration對象,它包含了HTTP請求頭部的所有項目名;
getMethod() —— 返回HTTP請求方式;
getRequestURL() —— 返回HTTP請求的頭部的第一行中的URL;
getQueryString() —— 返回HTTP請求中的查詢字符串,即URL中的“?”后面的內容;
 
 

 

響應

 
 
常用方法備注:
setCharacterEncoding() —— 設置相應正文的字符編碼。響應正文的默認字符編碼為ISO-8859-1;
setContentLength() —— 設置響應正文的長度;
setContentType() —— 設置響應正文的MIME類型;
getCharacterEncoding() —— 獲得響應正文的字符編碼
getContentType() —— 獲得響應正文的MIME類型
setBufferSize() —— 設置用於存放響應正文數據的緩沖區的大小
getBufferSize() —— 獲得用於存放響應正文數據的緩沖區的大小;
reset() —— 清空緩沖區內的正文數據,並且清空響應狀態代碼及響應頭
resetBuffer() —— 僅僅清空緩沖區的正文數據,不清空響應狀態代碼及響應頭;
flushBuffer() —— 強制性地把緩沖區內的響應正文數據發送到客戶端;
isCommitted() —— 返回一個boolean類型的值,如果為true,表示緩沖區內的數據已經提交給客戶,即數據已經發送到客戶端;
getOutputStream() —— 返回一個ServletOutputStream對象, Servlet用它來輸出二進制的正文數據
getWriter() —— 返回一個PrinterWriter對象, Servlet用它來輸出字符串形式的正文數據
ServletResponse中響應正文的默認MIME類型是text/plain,即純文本類型,而HttpServletResponse中響應正文的默認MIME類型為text/html,即HTML文檔類型。
 
為了提高輸出數據的效率,ServletOutputStream和PrintWriter首先把數據寫到緩沖區內。
當緩沖區內的數據被提交給客戶后,ServletResponse的isComitted方法返回true。
在以下幾種情況下,緩沖區內的數據會被提交給客戶,即數據被發送到客戶端:
  1. 當緩沖區內的數據已滿時,ServletOutPutStream或PrintWriter會自動把緩沖區內的數據發送給客戶端,並且清空緩沖區;
  2. Servlet調用ServletResponse對象的flushBuffer方法;
  3. Servlet調用ServletOutputStream或PrintWriter對象的flush方法或close方法;
如果要設置響應正文的MIME類型和字符編碼
必須先調用ServletResponse對象的setContentType()和setCharacterEncoding()方法,然后再調用ServletResponse的getOutputStream()或getWriter()方法
 
HttpServletResponse接口提供了與HTTP協議相關的一些方法,Servlet可通過這些方法來設置HTTP響應頭或向客戶端寫Cookie。
addHeader() —— 向HTTP響應頭中加入一項內容
sendError() —— 向客戶端發送一個代表特定錯誤的HTTP響應狀態代碼
setHeader() —— 設置HTTP響應頭中的一項內容,如果在響應頭中已經存在這項內容,則原來的設置被覆蓋
setStatus() —— 設置HTTP響應的狀態代碼
addCookie() —— 向HTTP響應中加入一個Cookie
 
在HttpServletResponse接口中定義了一些代表HTTP響應狀態代碼的靜態常量。
 

 
Servlet容器是調度機器 ,Servlet 是處理器   ,ServletRequest是請求,ServletResponse是響應
 
假設有一個小飯店,有老板和大廚,大廚就炒菜,老板干其他所有點菜收錢上菜
Servlet容器就好比飯店的服務員
Servlet 就是大廚 就負責炒菜
ServletRequest 就是點菜單
ServletResponse就是裝盤的菜
顯然:,服務員負責了所有的外圍操作,點菜下單到廚房(接收請求),端菜到餐桌(返回響應)
 
可以看得出來大廚除了炒菜什么都不做
老板做好了所有的外圍工作
 
 
 
對於大多數web項目來說 接收到的請求自然就是HTTP請求,響應也是HTTP響應
所以也可以說HttpServlet工作流程就是對HTTP的映射
 
所以說其實熟悉了HTTP 也就很容易就熟悉了 HttpServlet  HttpRequest HttpResponse 中的方法和屬性

 
javax.servlet

Interface ServletConfig

 
是Servlet的配置信息
servlet容器用於在Servlet初始化時傳遞信息的Servlet配置對象
一個Servlet對應一個ServletConfig
當servlet配置了初始化參數后,web容器在創建servlet實例對象時,會自動將這些初始化參數封裝到ServletConfig對象中
通過Servlet接口的init方法可以看得出來,init方法的參數
init方法由Servlet容器調用  Servlet容器將ServletConfig參數傳遞過來
    public void init(ServletConfig config) throws ServletException;
 
常用方法備注:
getInitParameter(String name) —— 返回匹配的初始化參數值
getInitParameterNames() —— 返回一個Enumeration對象,里面包含了所有的初始化參數名
getServletContext() —— 返回一個ServletContext對象
getServletName() —— 返回Servlet的名字,即web.xml文件中相應<servlet>元素的<servlet-name>子元素的值;如果沒有為servlet配置<servlet-name>子元素,則返回Servlet類的名字
 
已知實現類
GenericServlet, HttpServlet
也就是說:
HttpServlet類繼承了GenericServlet類,而GenericServlet類實現了ServletConfig接口,
因此HttpServlet或GenericServlet類及子類中都可以直接調用ServletConfig接口中的方法。
 

javax.servlet

Interface ServletContext

 
定義了servlet用來與servlet容器通信的一組方法,例如,獲取文件的MIME類型、分派請求或寫入日志文件。
一個web應用一個JVM只有一個Context
對於在其部署描述符中標記為“分布式”的web應用程序,此應用每個虛擬機都將有一個上下文實例
 
ServletContext對象包含在ServletConfig對象中,ServletConfig是Web服務器在servlet被初始化時,提供給servlet。
所以可以使用:
Servlet.getServletConfig()
ServletConfig.getServletContext() 
獲取Context
 
一個應用一個JVM只有一個Context也就是所有應用共享的
 
常用方法備注:
ServletContext接口提供的方法可以分為以下幾種類型:
用於在web應用范圍內存取共享數據的方法
setAttribute(String name, Object object) —— 把一個Java對象與一個屬性名綁定,並存入到ServletContext中;
getAttribute() —— 返回指定數姓名的屬性值
getAttributeNames() —— 返回一個Enumeration對象,包含所有存放在ServletContext中的屬性名
removeAttributes() —— 從ServletContext中刪除匹配的屬性
訪問當前Web應用的資源
getContextPath() —— 返回當前Web應用的URL入口
getInitParameter() —— 返回Web應用范圍內的匹配的初始化參數值。在web.xml中,直接在<web-app>根元素下定義的<context-param>元素表示應用范圍內的初始化參數
getServletContextName() —— 返回Web應用的名字,即web.xml文件中<display-name>元素的值
getRequestDispatcher() —— 返回一個用於向其他WEB組件轉發請求的RequestDispatcher對象
訪問Servlet容器中的其他WEB應用
訪問Servlet容器的相關信息
訪問服務器端的文件系統資源
getRealPath() —— 根據參數指定的虛擬路徑,返回文件系統中的一個真實的路徑
getResources() —— 返回一個映射到參數指定的路徑的URL
getResourceAsStream() —— 返回一個用於讀取參數指定的文件的輸入流
getMimeType() —— 返回參數指定的文件MIME類型
輸出日志
log(String msg) —— 向Servlet的日志文件中寫日志
log(String message, Throwable throwable) —— 向Servlet的日志文件中寫入錯誤日志,以及異常的堆棧信息
 
 

 
總結:
 
Servlet容器比如tomcat
負責創建/調用/銷毀 Servlet
對於大多數程序員來說需要做的就是編寫Servlet類一般繼承HTTPServlet就可以了
 
Web.xml中可以配置ServletContext以及ServletConfig的信息
tomcat 初始化Servlet的時候會將ServletConfig傳給Servlet,通過ServletConfig又可以獲取到ServletContext
每次的請求時,Servlet容器將請求進行封裝ServletRequest,傳遞給Servlet,我們可以在Servlet中解析請求,根據請求作出相應的響應
響應信息通過ServletResponse傳遞回去
這就是一個Servlet被調用的大致過程
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM