国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JAVA WEB中Servlet和Servlet容器的區(qū)別

瀏覽:43日期:2022-08-30 10:11:30

Servlet

很多同學(xué)可能跟我一樣始終沒(méi)有搞清楚到底什么是 Servlet,什么是 Servlet 容器。網(wǎng)上看了很多帖子,或許人家說(shuō)的很清楚,但是自己的那個(gè)彎彎就是拐不過(guò)來(lái)。

想了很久說(shuō)一下自己的理解。

Java web 開發(fā)中為啥要有 Servlet 呢?是否可以不要。

web開發(fā)的本質(zhì)就一句話:客戶端和服務(wù)器交換數(shù)據(jù)。于是你使用 Java 的 Socket 套接字進(jìn)行編程,去處理客戶端來(lái)的 tcp 請(qǐng)求,經(jīng)過(guò)編解碼處理讀取請(qǐng)求體,獲取請(qǐng)求行,然后找到請(qǐng)求行對(duì)應(yīng)的處理邏輯步入服務(wù)器的處理中,處理完畢把對(duì)應(yīng)的結(jié)果返回給當(dāng)前的 Socket 鏈接,響應(yīng)完畢,關(guān)閉 Socket。

以上過(guò)程,你有沒(méi)有發(fā)現(xiàn)其實(shí)是兩個(gè)部分:

建立連接,傳輸數(shù)據(jù),關(guān)閉連接,你肯定知道這些步驟不是你所開發(fā)的web服務(wù)去處理的,而是tomcat容器幫你做了這些事情。

拿到請(qǐng)求行之后去找對(duì)應(yīng)的 url 路由,這一部分是誰(shuí)做的呢?在如今 SpringBoot 橫行的時(shí)代,去配置化已經(jīng)成為趨勢(shì),編程越來(lái)越簡(jiǎn)單導(dǎo)致的后果就是越來(lái)越難以理解事物最開始的樣子。還記得 SpringMVC工程中的 web.xml文件嗎?是否還記得在web.xml中有這么一段配置呢:

<servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath*:/spring/SpringMVC-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>SpringMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping>

Spring 的核心就是一個(gè) Servlet,它攔截了所有的請(qǐng)求,將請(qǐng)求交給 DispatcherServlet 去處理。我們?cè)賮?lái)問(wèn)一遍,Servlet 到底是什么,它就是一段處理 web 請(qǐng)求的邏輯,并不是很高深的東西。

再來(lái)看 Java 中的 Servlet,它只是一個(gè)接口:

package javax.servlet;import java.io.IOException;public interface Servlet { public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; public String getServletInfo(); public void destroy();}

Servlet 接口規(guī)定請(qǐng)求從容器到達(dá) web 服務(wù)端的規(guī)范,最重要的三個(gè)步驟是:

init():初始化請(qǐng)求的時(shí)候要做什么; service():拿到請(qǐng)求的時(shí)候要做什么; destory():處理完請(qǐng)求銷毀的時(shí)候要做什么。

所有實(shí)現(xiàn) Servlet 的實(shí)現(xiàn)方都是在這個(gè)規(guī)范的基礎(chǔ)上進(jìn)行開發(fā)。那么 Servlet 中的數(shù)據(jù)是從哪里來(lái)的呢?答案就是 Servlet 容器。容器才是真正與客戶端打交道的那一方。Servlet容器只有一個(gè),而 Servlet 可以有多個(gè)。常見的Servlet容器Tomcat,它監(jiān)聽了客戶端的請(qǐng)求端口,根據(jù)請(qǐng)求行信息確定將請(qǐng)求交給哪個(gè)Servlet 處理,找到處理的Servlet之后,調(diào)用該Servlet的 service() 方法,處理完畢將對(duì)應(yīng)的處理結(jié)果包裝成ServletResponse 對(duì)象返回給客戶端。

Servlet 容器

上面說(shuō)過(guò),Servlet 只是一個(gè)處理請(qǐng)求的應(yīng)用程序,光有Servlet是無(wú)法運(yùn)行起來(lái)的,需要有一個(gè) main 方法去調(diào)用你的這段 Servlet 程序才行。所以這里出現(xiàn)了Servlet 容器的概念。Servlet容器的主要作用是:

建立連接; 調(diào)用Servlet處理請(qǐng)求; 響應(yīng)請(qǐng)求給客戶端; 釋放連接;

這上面的四步,如果是你來(lái)設(shè)計(jì)的話是否可以用一個(gè)模板方法搞定,1,3,4都是固定的步驟,不會(huì)因?yàn)檎?qǐng)求不同而有很大的變化。2卻會(huì)因?yàn)閷?duì)應(yīng)的請(qǐng)求不同需要業(yè)務(wù)邏輯自己去實(shí)現(xiàn)不同的處理。所以這里抽象出來(lái)了 Servlet,Servlet想怎么玩就怎么玩,這是你自己的事情。容器幫你做的是你不想做的臟活累活。

另外,既然叫做容器肯定是能裝多個(gè)Servlet,并且可以管理Servlet的聲明周期。這些功能應(yīng)該是容器必備的。

上面提到了 web.xml 中的 DispatcherServlet,它是 Spring 中定義的一個(gè) Servlet,實(shí)現(xiàn)了 Servlet 接口,本質(zhì)也是一個(gè) Servlet。只是它是 HttpServlet 的繼承者,主要處理 http 請(qǐng)求。所以 Spring 程序本質(zhì)是就是一個(gè) Servlet。SpringMVC 幫你做了本該你去實(shí)現(xiàn)的邏輯,你看不到并不代表它不是。

好啦,以上通俗的語(yǔ)言解釋了什么是 Servlet,什么是 Servlet 容器,以及 Servlet 和 Servlet 容器之間的關(guān)系。

Tomcat

Tomcat是啥呢?本質(zhì)上是一個(gè) Servlet 容器,實(shí)現(xiàn)了對(duì) Java Servlet 規(guī)范的支持。同時(shí) Tomcat 也提供了處理HTTP請(qǐng)求的能力,所以也可以作為一個(gè)Web服務(wù)器。了解到Tomcat有 Web服務(wù)器和 Servlet容器的功能,那么 Tomcat總體是如何設(shè)計(jì)的呢?我們來(lái)看一張簡(jiǎn)圖:

JAVA WEB中Servlet和Servlet容器的區(qū)別

Java web 應(yīng)用如果部署到 Tomcat 中,一個(gè)Tomcat就表示一個(gè)服務(wù)。一個(gè) Server 服務(wù)器可以包含多個(gè) Service 服務(wù),Tomcat 默認(rèn)的 Service 服務(wù)是 Catalina,而一個(gè) Service 服務(wù)可以包含多個(gè)連接器,因?yàn)?Tomcat 支持多種網(wǎng)絡(luò)協(xié)議,包括 HTTP/1.1、HTTP/2、AJP 等等,一個(gè) Service 服務(wù)還會(huì)包括一個(gè)容器,容器外部會(huì)有一層 Engine 引擎所包裹,負(fù)責(zé)與處理連接器的請(qǐng)求與響應(yīng),連接器與容器之間通過(guò) ServletRequest 和 ServletResponse 對(duì)象進(jìn)行交流。

Tomcat容器的設(shè)計(jì)提現(xiàn)在一個(gè)核心文件中:server.xml。這個(gè)文件充分展示了Tomcat的高度抽象設(shè)計(jì):

<Server port='8005' shutdown='SHUTDOWN'> <Service name='Catalina'> <Connector port='8080' protocol='HTTP/1.1' connectionTimeout='20000' redirectPort='8443'/> <Connector port='8009' protocol='AJP/1.3' redirectPort='8443'/><Engine name='Catalina' defaultHost='localhost'> <Host name='localhost' appBase='webapps' unpackWARs='true' autoDeploy='true'> </Host> </Engine> </Service></Server>

其中:

1. Server 組件是管理 tomcat 實(shí)例的組件,可以監(jiān)聽一個(gè)端口,從此端口上可以遠(yuǎn)程向該實(shí)例發(fā)送 shutdown 關(guān)閉命令。

2. Service 組件是一個(gè)邏輯組件,用于綁定 connector 和 container,有了 service 表示可以向外提供服務(wù),就像是一般的 daemon 類服務(wù)的 service。可以認(rèn)為一個(gè) service 就啟動(dòng)一個(gè)JVM,更嚴(yán)格地說(shuō),一個(gè) engine 組件才對(duì)應(yīng)一個(gè) JVM (定義負(fù)載均衡時(shí),jvmRoute 就定義在 Engine 組件上用來(lái)標(biāo)識(shí)這個(gè) JVM ),只不過(guò) connector 也工作在 JVM 中。

小故事:

是否關(guān)注到 Service name = Catalina,實(shí)際上 Tomcat 的前身就是 Catalina,這是一個(gè)島的名字,而

Catalina 只是一個(gè) Servlet 容器,為Servlet和 JavaServer Pages(JSP)實(shí)現(xiàn)了Sun Microsystems的規(guī)范。

Tomcat 的作者 詹姆斯·鄧肯·戴維森,Sun Microsystems 的軟件架構(gòu)師在后來(lái) Sun Microsystems 向 Apache Software Foundation 捐贈(zèng)該項(xiàng)目中發(fā)揮了重要作用。當(dāng)時(shí)他認(rèn)為許多開源項(xiàng)目都有與 O’Reilly 相關(guān)的書籍,封面上有動(dòng)物,所以他想以動(dòng)物命名。后來(lái)這位老哥想到了貓🐈。他認(rèn)為這只動(dòng)物代表著某種可以自己生存的東西,當(dāng)2003年 O’Reilly 發(fā)行帶有雪豹的 Tomcat 書籍時(shí),他希望看到動(dòng)物封面的愿望終于實(shí)現(xiàn)了。

3. Connector 組件是監(jiān)聽組件,它有四個(gè)作用:

開啟監(jiān)聽套接字,監(jiān)聽外界請(qǐng)求,并和客戶端建立 TCP 連接; 使用 protocolHandler 解析請(qǐng)求中的協(xié)議和端口等信息,如 http 協(xié)議、AJP 協(xié)議; 根據(jù)解析到的信息,使用 processer 將分析后的請(qǐng)求轉(zhuǎn)發(fā)給綁定的 Engine; 接收響應(yīng)數(shù)據(jù)并返回給客戶端。

上面的 server.xml 配置我們能看到有兩個(gè) Connector。

<Connector port='8080' protocol='HTTP/1.1' connectionTimeout='20000' redirectPort='8443'/>

這個(gè) Connector 表示通過(guò) 8080 端口使用 HTTP/1.1版本的協(xié)議來(lái)訪問(wèn) Tomcat。

我們知道 80 端口是為 HTTP(HyperText Transport Protocol) 即 超文本傳輸協(xié)議 開放的,主要用于萬(wàn)維網(wǎng)傳輸信息的協(xié)議。而我們一般在 Tomcat 中監(jiān)聽的是一個(gè)非 80 端口。那為啥不直接在 Tomcat 中寫上 80 端口,即所有 HTTP 請(qǐng)求都可以收到。這是因?yàn)樵谏a(chǎn)環(huán)境中,一般不會(huì)直接暴露原始服務(wù)給外網(wǎng),一方面是安全性,另一方面是 負(fù)載均衡處理 和 靜態(tài)資源處理。所以會(huì)在原始服務(wù)上加一層代理,代理來(lái)監(jiān)聽 80 端口,再將服務(wù)暴露端口的請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)服務(wù)。

第二個(gè) Connector:

<Connector port='8009' protocol='AJP/1.3' redirectPort='8443'/>

這個(gè) Connector 監(jiān)聽 8009 端口的 AJP 協(xié)議連接。AJP 協(xié)議負(fù)責(zé)和其他的 HTTP 服務(wù)器(如 Apache )建立連接;在把 Tomcat 與其他 HTTP 服務(wù)器集成時(shí),就需要用到這個(gè)連接器。之所以使用 Tomcat 和其他服務(wù)器集成,是因?yàn)?Tomcat 可以用作 Servlet/JSP 容器,但是對(duì)靜態(tài)資源的處理速度較慢,不如 Apache 和 IIS 等 HTTP 服務(wù)器。因此常常將 Tomcat 與 Apache 等集成,前者作 Servlet 容器,后者處理靜態(tài)資源,而 AJP 協(xié)議便負(fù)責(zé) Tomcat 和 Apache 的連接。

Container 表示一類組件,在配置文件(server.xml)中沒(méi)有體現(xiàn)出來(lái)。它包含4個(gè)容器類組件:Engine容器、Host容器、Context容器 和 wrapper容器。

Engine 容器用于從 Connector 組件處接收已建立的 TCP 連接,還用于接收客戶端發(fā)送的 HTTP 請(qǐng)求并分析請(qǐng)求,然后按照分析的結(jié)果將相關(guān)參數(shù)傳遞給匹配出的虛擬主機(jī)。Engine 還用于指定默認(rèn)的虛擬主機(jī)。

Host 容器定義虛擬主機(jī),對(duì)應(yīng)了服務(wù)器中一個(gè)網(wǎng)絡(luò)名實(shí)體(如”www.baidu.com”,或IP地址”23.0.32.1”)。為了使用戶可以通過(guò)域名連接 Tomcat 服務(wù)器,這個(gè)域名應(yīng)該在域名服務(wù)器已經(jīng)注冊(cè)過(guò)。

比如上例中的配置:

<Host name='localhost' appBase='webapps' unpackWARs='true' autoDeploy='true'>

name=localhost 表示當(dāng)前對(duì)應(yīng)的請(qǐng)求是本機(jī),這是因?yàn)橐呀?jīng)配置了Nginx代理的原因,如果沒(méi)有配置代理,那么這里就必須是真實(shí)的IP 或者域名。注意后面的 appBase,appBase表示當(dāng)前 web資源所在的目錄。

Context 容器主要是根據(jù) path 和 docBase 獲取一些信息,將結(jié)果交給其內(nèi)的 wrapper 組件進(jìn)行處理(它提供wrapper運(yùn)行的環(huán)境,所以它叫上下文context)。一般來(lái)說(shuō),都采用默認(rèn)的標(biāo)準(zhǔn) wrapper 類,因此在 Context 容器中幾乎不會(huì)出現(xiàn) wrapper 組件。

wrapper 容器對(duì)應(yīng) Servlet 的處理過(guò)程。它開啟 Servlet 的生命周期,根據(jù) Context 給出的信息以及解析 web.xml 中的映射關(guān)系,負(fù)責(zé)裝載相關(guān)的類,初始化 servlet 對(duì)象 init()、執(zhí)行 servlet 代碼 service() 以及服務(wù)結(jié)束時(shí) servlet 對(duì)象的銷毀 destory()。

根據(jù)上面描述的 tomcat 組件體系結(jié)構(gòu),處理請(qǐng)求的大致過(guò)程其實(shí)很容易推導(dǎo)出來(lái):

Client(request)-->Connector-->Engine-->Host-->Context-->Wrapper(response data)-->Connector(response header)-->Client

可以看到宏觀上 Tomcat 設(shè)計(jì)的真是非常精妙,層疊式的容器設(shè)計(jì)呈現(xiàn)出一種美感。Connector 和 Container 兩大組件涵蓋主要功能,這種復(fù)合組件化的設(shè)計(jì)思想我們是否可以應(yīng)用在業(yè)務(wù)系統(tǒng)中呢。右面有空繼續(xù)分析 Tomcat 中各個(gè)模塊的設(shè)計(jì)。

以上就是JAVA WEB中Servlet和Servlet容器的區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于JAVA WEB Servlet和Servlet容器的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 黄色天堂 | 中文国产成人精品久久水 | 成人在线视频国产 | dvd8090cnm欧美大片 | 99国产精品欧美久久久久久影院 | 亚洲国产精品久久久天堂 | 亚洲国产亚洲片在线观看播放 | 美女毛片免费看 | 最近中文字幕免费视频 | 亚洲精品永久一区 | 日本阿v视频在线观看高清 日本波多野结衣视频 | 99国产福利视频在线观看 | 免费一级片视频 | 久久亚洲精品中文字幕第一区 | 99在线免费观看视频 | 免费一级片视频 | 国产精品久久毛片蜜月 | 黄色美女视频网站 | 日本欧美视频在线 | 久草网视频在线观看 | 成年美女黄网站小视频 | 日本美女一区二区三区 | 亚洲综合久久久久久中文字幕 | 日本黄页网站免费大全 | 成人a视频片在线观看免费 成人a视频在线观看 | 日韩欧美国产另类 | 国产成人精品免费久久久久 | 久久91综合国产91久久精品 | 男人好大好硬好爽免费视频 | 欧美日韩高清观看一区二区 | 中文字幕在线观看一区 | 亚洲国产日韩女人aaaaaa毛片在线 | 人碰人碰人成人免费视频 | 成人满18在线观看网站免费 | 久久精品国产亚洲7777 | 欧美经典成人在观看线视频 | 在线a网站| 久久成人免费网站 | 成 人 黄 色 激 情视频网站 | 国产精品99久久久久久人 | 视频一区在线免费观看 |