servlet/tomcat等容器/springMVC之間的關(guān)系

Servlet是什么恬砂?

Servlet是JavaEE規(guī)范的一種,主要是為了擴(kuò)展Java作為Web服務(wù)的功能蓬痒,統(tǒng)一接口觉既。由其他內(nèi)部廠商如tomcat,jetty內(nèi)部實(shí)現(xiàn)web的功能乳幸。如一個(gè)http請(qǐng)求到來:
容器將請(qǐng)求封裝為servlet中的HttpServletRequest對(duì)象瞪讼,調(diào)用init(),service()等方法輸出response,由容器包裝為httpresponse返回給客戶端的過程粹断。

servlet工作模式.jpg

在Servlet規(guī)范中符欠,提供了ServletContext,ServletRequest,ServletResponse,Filter等諸多接口。
基本類圖和調(diào)用關(guān)系如下:
image.png

請(qǐng)求調(diào)用關(guān)系

下面簡(jiǎn)要介紹下接口的作用瓶埋,生命周期和使用:
Servlet:
作用:用于處理請(qǐng)求(service方法)
生命周期:加載實(shí)例化希柿、初始化、處理客戶端請(qǐng)求养筒、銷毀曾撤。
加載實(shí)例化主要是交由web容器完成,而其他三個(gè)階段則對(duì)應(yīng)Servlet的init晕粪、service和destroy方法挤悉。Servlet對(duì)象被創(chuàng)建出來后需要對(duì)其進(jìn)行初始化操作,初始化工作可以放在以ServletConfig類型為參數(shù)的ini方法中巫湘,ServletConfig為web.xml配置文件中配置的對(duì)應(yīng)的初始化參數(shù)装悲,由web容器完成web.xml配置讀取并封裝成ServletConfig對(duì)象;當(dāng)Servlet初始化完成后尚氛,開始接受客戶端的請(qǐng)求诀诊,這些請(qǐng)求被封裝成ServletRequest類型的請(qǐng)求對(duì)象和ServletResponse類型的響應(yīng)對(duì)象,通過service方法處理請(qǐng)求并響應(yīng)客戶端阅嘶;當(dāng)一個(gè)Servlet需要從web容器中移除時(shí)属瓣,就會(huì)調(diào)用對(duì)應(yīng)的destroy方法用于釋放所有的資源,并且調(diào)用destroy方法之前要保證所有正在執(zhí)行service方法的線程都完成執(zhí)行讯柔。
使用:servlet規(guī)范中定義了GenericServlet接口抡蛙,定義了通用,協(xié)議獨(dú)立的servlet,他們的子接口HttpServlet就是用來處理http請(qǐng)求的Servlet,根據(jù)http協(xié)議擴(kuò)展了不同方式的請(qǐng)求處理方法磷杏,如doPost,doGet.

ServletContext:Servlet與Servlet容器之間直接通信的接口,一個(gè)web應(yīng)用只獨(dú)有一個(gè)ServletContext.
作用:

  • 用于在web應(yīng)用范圍內(nèi)存取共享數(shù)據(jù),如setAttribute(String name, Object object)溜畅,getAttribute()
  • 獲取當(dāng)前Web應(yīng)用的資源,如getContextPath()
  • 獲取服務(wù)器端的文件系統(tǒng)資源极祸,如getResourceAsStream()
  • 輸出日志慈格,如log(String msg) : 向Servlet的日志文件中寫日志
  • 在具體ServletContext 實(shí)現(xiàn)中,提供了添加Servlet遥金,F(xiàn)ilter,Listener到ServletContext里面的方法
    生命周期:和web應(yīng)用的生命周期一樣
    使用:一般由web容器實(shí)現(xiàn)浴捆,如tomcat

Filter:
作用:用于Web容器對(duì)請(qǐng)求和響應(yīng)做統(tǒng)一處理,例如統(tǒng)一改變HTTP請(qǐng)求內(nèi)容和響應(yīng)內(nèi)容稿械,它可以作用在某個(gè)Servlet或一組Servlet
生命周期:加載實(shí)例化选泻、初始化(init)、處理客戶端請(qǐng)求(doFilter)、銷毀(destroy)
使用:在doFilter方法中調(diào)用chain.doFilter(request, response)之前的代碼可用來做一些請(qǐng)求校驗(yàn)页眯,之后代碼可用來做一些響應(yīng)包裝梯捕。

ServletRequest:封裝了客戶端請(qǐng)求的所有信息,如果使用HTTP協(xié)議通信則包括HTTP協(xié)議的請(qǐng)求行和請(qǐng)求頭窝撵。HTTP協(xié)議對(duì)應(yīng)請(qǐng)求對(duì)象類型是HttpServletRequest類
作用:

  • 獲取HTTP協(xié)議請(qǐng)求頭部傀顾,如getHeader、getHeaders
  • 獲取請(qǐng)求路徑碌奉,如getContextPath短曾、getServletPath
  • 獲取cookie的方法,如getCookies
  • 獲取session的方法赐劣,如getSession,session是存儲(chǔ)在服務(wù)器內(nèi)存中嫉拐,返回響應(yīng)的時(shí)候會(huì)寫入瀏覽器一個(gè)sessionId的cookie,用來標(biāo)示這一個(gè)會(huì)話

生命周期:只在servlet的service方法或過濾器的doFilter方法作用域內(nèi)有效魁兼,除非啟用了異步處理調(diào)用了ServletRequest接口對(duì)象的startAsync方法婉徘,此時(shí)request對(duì)象會(huì)一直有效,直到調(diào)用AsyncContext的complete方法璃赡。另外判哥,web容器通常會(huì)為了性能而不銷毀ServletRequest接口的對(duì)象,而是重復(fù)利用ServletRequest接口對(duì)象碉考。

ServletResponse:Servlet通過ServletResponse對(duì)象來生成響應(yīng)結(jié)果塌计。
作用:定義了一系列與生成響應(yīng)結(jié)果相關(guān)的方法,如:

  • setCharacterEncoding() —— 設(shè)置相應(yīng)正文的字符編碼侯谁。響應(yīng)正文的默認(rèn)字符編碼為ISO-8859-1锌仅;
  • setContentLength() —— 設(shè)置響應(yīng)正文的長(zhǎng)度;
  • setBufferSize() —— 設(shè)置用于存放響應(yīng)正文數(shù)據(jù)的緩沖區(qū)的大小
  • getBufferSize() —— 獲得用于存放響應(yīng)正文數(shù)據(jù)的緩沖區(qū)的大星郊热芹;
  • reset() —— 清空緩沖區(qū)內(nèi)的正文數(shù)據(jù),并且清空響應(yīng)狀態(tài)代碼及響應(yīng)頭
  • resetBuffer() —— 僅僅清空緩沖區(qū)的正文數(shù)據(jù)惨撇,不清空響應(yīng)狀態(tài)代碼及響應(yīng)頭伊脓;
  • flushBuffer() —— 強(qiáng)制性地把緩沖區(qū)內(nèi)的響應(yīng)正文數(shù)據(jù)發(fā)送到客戶端;
  • isCommitted() —— 返回一個(gè)boolean類型的值魁衙,如果為true报腔,表示緩沖區(qū)內(nèi)的數(shù)據(jù)已經(jīng)提交給客戶,即數(shù)據(jù)已經(jīng)發(fā)送到客戶端剖淀;
  • getOutputStream() —— 返回一個(gè)ServletOutputStream對(duì)象纯蛾,Servlet用它來輸出二進(jìn)制的正文數(shù)據(jù);
  • getWriter() —— 返回一個(gè)PrinterWriter對(duì)象纵隔,Servlet用它來輸出字符串形式的正文數(shù)據(jù)翻诉;

為了提高輸出數(shù)據(jù)的效率炮姨,ServletOutputStream和PrintWriter首先把數(shù)據(jù)寫到緩沖區(qū)內(nèi)。當(dāng)緩沖區(qū)內(nèi)的數(shù)據(jù)被提交給客戶后碰煌,ServletResponse的isComitted方法返回true舒岸。

生命周期:ServletResponse接口只在Servlet的service方法或過濾器的doFilter方法作用域內(nèi)有效,除非它關(guān)聯(lián)的ServletResponse接口調(diào)用了startAsync方法啟用異步處理拄查,此時(shí)ServletResponse接口會(huì)一直有效吁津,直到調(diào)用AsyncContext的complete方法。另外堕扶,web容器通常會(huì)為了性能而不銷毀ServletResponse接口對(duì)象,而是重復(fù)利用ServletResponse接口對(duì)象梭依。

Listener:當(dāng)觸發(fā)某個(gè)事件稍算,如servlet context初始化完成時(shí),需要做一些事情役拴,servlet規(guī)范中定義了若干個(gè)Listener用于監(jiān)聽這些事件糊探。
作用:用于對(duì)特定對(duì)象的生命周期和特定事件進(jìn)行響應(yīng)處理,主要用于對(duì)Session,request,context等進(jìn)行監(jiān)控河闰。

監(jiān)聽域?qū)ο笞陨淼膭?chuàng)建和銷毀的事件監(jiān)聽器

  • ServletContextListener:ServletContext的創(chuàng)建和銷毀:contextInitialized方法和contextDestroyed方法科平,作為定時(shí)器、加載全局屬性對(duì)象姜性、創(chuàng)建全局?jǐn)?shù)據(jù)庫(kù)連接瞪慧、加載緩存信息等
  • HttpSessionListener:HttpSession的創(chuàng)建和銷毀:sessionCreated和sessionDestroyed方法,可用于統(tǒng)計(jì)在線人數(shù)部念、記錄訪問日志等
  • ServletRequestListener: ServletRequest的創(chuàng)建和銷毀:requestInitialized和requestDestroyed方法

監(jiān)聽域?qū)ο笾械膶傩缘脑黾雍蛣h除的事件監(jiān)聽器

  • ServletContextAttributeListener弃酌、HttpSessionAttributeListener、ServletRequestAttributeListener接口儡炼。
  • 實(shí)現(xiàn)方法:attributeAdded妓湘、attributeRemoved、attributeReplaced

監(jiān)聽綁定到HttpSeesion域中的某個(gè)對(duì)象的狀態(tài)的事件監(jiān)聽器(創(chuàng)建普通JavaBean)

  • HttpSession中的對(duì)象狀態(tài):綁定→解除綁定乌询;鈍化→活化
  • 實(shí)現(xiàn)接口及方法:HttpSessionBindingListener接口(valueBound和valueUnbound方法)榜贴、HttpSessionActivationListener接口(sessionWillPassivate和sessionDidActivate方法)

tomcat是什么?

tomcat等容器其實(shí)就是web服務(wù)的實(shí)現(xiàn)妹田,暴露端口唬党,按照特定資源URL找到處理的servlet。然后處理請(qǐng)求秆麸。
web.xml其實(shí)tomcat在啟動(dòng)時(shí)候需要加載的配置歡迎頁初嘹、Filter、Listener沮趣、Servlet等類的定義屯烦。當(dāng)然不止加載這些東西,這些東西是需要加載到JVM堆內(nèi)存中實(shí)例化的對(duì)象。
Tomcat啟動(dòng)時(shí)加載資源主要有三個(gè)階段:

  • 第一階段:JVM相關(guān)資源
(1)$JAVA_HOME/jre/lib/ext/*.jar
(2)系統(tǒng)classpath環(huán)境變量中的*.jar和*.class 
  • 第二階段:Tomcat自身相關(guān)資源
(1)$CATALINA_HOME/common/classes/*.class  
(2)$CATALINA_HOME/commons/endorsed/*.jar   
(3)$CATALINA_HOME/commons/i18n/*.jar   
(4)$CATALINA_HOME/common/lib/*.jar   
(5)$CATALINA_HOME/server/classes/*.class   
(6)$CATALINA_HOME/server/lib/*.jar   
(7)$CATALINA_BASE/shared/classes/*.class   
(8)$CATALINA_BASE/shared/lib/*.jar 
  • 第三階段:Web應(yīng)用相關(guān)資源
(1)具體應(yīng)用的webapp目錄: /WEB-INF/classes/*.class   
(2)具體應(yīng)用的webapp: /WEB-INF/lib/*.jar

在tomcat目錄${CATALINA_HOME}/conf下和web應(yīng)用目錄${CATALINA_HOME}/webapps/WebDemo(WebDemo為web應(yīng)用名)下都有web.xml這個(gè)文件驻龟,但是內(nèi)容不一樣温眉。

Tomcat在激活、加載翁狐、部署web應(yīng)用時(shí)类溢,會(huì)解析加載${CATALINA_HOME}/conf目錄下所有web應(yīng)用通用的web.xml,然后解析加載web應(yīng)用目錄中的WEB-INF/web.xml露懒。
其實(shí)根據(jù)他們的位置闯冷,我們就可以知道,conf/web.xml文件中的設(shè)定會(huì)應(yīng)用于所有的web應(yīng)用程序懈词,而某些web應(yīng)用程序的WEB-INF/web.xml中的設(shè)定只應(yīng)用于該應(yīng)用程序本身蛇耀。

如果沒有WEB-INF/web.xml文件,tomcat會(huì)輸出找不到的消息坎弯,但仍然會(huì)部署并使用web應(yīng)用程序纺涤,servlet規(guī)范的作者想要實(shí)現(xiàn)一種能迅速并簡(jiǎn)易設(shè)定新范圍的方法,以用作測(cè)試抠忘,因此撩炊,這個(gè)web.xml并不是必要的,不過通常最好還是讓每一個(gè)上線的web應(yīng)用程序都有一個(gè)自己的WEB-INF/web.xml崎脉。

web.xml中可以配置web應(yīng)用名稱拧咳,圖標(biāo),描述荧嵌,ServletContext上下文參數(shù)呛踊,F(xiàn)liter配置,Listener配置啦撮,Servlet配置谭网,會(huì)話超時(shí)配置,MIME類型配置等等赃春。

Spring MVC 是什么愉择?

Spring MVC (SpringBoot)其實(shí)就是基于tomcat等這些web容器對(duì)我們的CS請(qǐng)求能做更多的事情,如校驗(yàn)织中,攔截(AOP思想)锥涕,后期渲染等等,好讓我們專注于業(yè)務(wù)的開發(fā)狭吼。
Springmvc的核心是一個(gè)DispatcherServlet层坠,負(fù)責(zé)請(qǐng)求的解析,攔截刁笙,轉(zhuǎn)發(fā)破花,響應(yīng)等等谦趣。相關(guān)類圖和請(qǐng)求處理流程為:



其中FrameworkServlet會(huì)和Spring的ApplicationContext聯(lián)系起來,它實(shí)現(xiàn)了ApplicationContextAware接口座每。



當(dāng)然Spring MVC框架也提供rest訪問前鹅,從而可實(shí)現(xiàn)前后端的分離。
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestfulWebServiceController {

    @GetMapping("/message")
    public MyOutputResource getMessage() {
        return new MyOutputResource("Hello!");
    }
}

感謝您的閱讀峭梳,我是Monica23334 || Monica2333 舰绘。立下每周寫一篇原創(chuàng)文章flag的小姐姐,關(guān)注我并期待打臉吧~

參考資料:
Java Servlet 3.1 規(guī)范
servlet的本質(zhì)是什么葱椭,它是如何工作的捂寿?
Servlet規(guī)范總結(jié)
【Java.Web】Servlet —— Servlet的類的體系結(jié)構(gòu)
Servlet 工作原理解析
Cookie 與 Session 的區(qū)別
Session原理和Tomcat實(shí)現(xiàn)分析
An Introduction to Tomcat Servlet Interactions
關(guān)于web.xml配置的那些事兒
How Spring Web MVC Really Works

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市挫以,隨后出現(xiàn)的幾起案子者蠕,更是在濱河造成了極大的恐慌,老刑警劉巖掐松,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異粪小,居然都是意外死亡大磺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門探膊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杠愧,“玉大人,你說我怎么就攤上這事逞壁×骷茫” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵腌闯,是天一觀的道長(zhǎng)绳瘟。 經(jīng)常有香客問我,道長(zhǎng)姿骏,這世上最難降的妖魔是什么糖声? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮分瘦,結(jié)果婚禮上蘸泻,老公的妹妹穿的比我還像新娘。我一直安慰自己嘲玫,他們只是感情好悦施,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著去团,像睡著了一般抡诞。 火紅的嫁衣襯著肌膚如雪穷蛹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天沐绒,我揣著相機(jī)與錄音俩莽,去河邊找鬼。 笑死乔遮,一個(gè)胖子當(dāng)著我的面吹牛扮超,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蹋肮,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼出刷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了坯辩?” 一聲冷哼從身側(cè)響起馁龟,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漆魔,沒想到半個(gè)月后坷檩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡改抡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年矢炼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阿纤。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡句灌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欠拾,到底是詐尸還是另有隱情胰锌,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布藐窄,位于F島的核電站资昧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏枷邪。R本人自食惡果不足惜榛搔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望东揣。 院中可真熱鬧践惑,春花似錦、人聲如沸嘶卧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芥吟。三九已至侦铜,卻和暖如春专甩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钉稍。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工涤躲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贡未。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓种樱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親俊卤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嫩挤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容