java基礎(chǔ)學(xué)習(xí):JavaWeb之Servlet

其他更多java基礎(chǔ)文章:
java基礎(chǔ)學(xué)習(xí)(目錄)


什么是Servlet

Servlet是一個特殊的Java類泥兰, 是運(yùn)行在 Web 服務(wù)器中的小型 Java 程序(即:服務(wù)器端的小應(yīng)用程序)。servlet 通常通過 HTTP(超文本傳輸協(xié)議)接收和響應(yīng)來自 Web 客戶端的請求昼浦。這個Java類必須繼承HttpServlet。每個Servlet可以響應(yīng)客戶端的請求筒主,Servlet提供不同的方法用于響應(yīng)客戶端請求关噪,例如doGet,doPost乌妙,doPut等

Tomcat與Servlet的關(guān)系

Tomcat 是Web應(yīng)用服務(wù)器,是一個Servlet/JSP容器. Tomcat 作為Servlet容器,負(fù)責(zé)處理客戶請求,把請求傳送給Servlet,并將Servlet的響應(yīng)傳送回給客戶.而Servlet是一種運(yùn)行在支持Java語言的服務(wù)器上的組件.使兔。

Servlet最常見的用途是擴(kuò)展Java Web服務(wù)器功能,提供非常安全的,可移植的,易于使用的CGI替代品。
從http協(xié)議中的請求和響應(yīng)可以得知冠胯,瀏覽器發(fā)出的請求是一個請求文本,而瀏覽器接收到的也應(yīng)該是一個響應(yīng)文本锦针。


image
  1. Tomcat將http請求文本接收并解析荠察,然后封裝成HttpServletRequest類型的request對象置蜀,所有的HTTP頭數(shù)據(jù)讀可以通過request對象調(diào)用對應(yīng)的方法查詢到。
  2. Tomcat同時會要響應(yīng)的信息封裝為HttpServletResponse類型的response對象悉盆,通過設(shè)置response屬性就可以控制要輸出到瀏覽器的內(nèi)容盯荤,然后將response交給tomcat,tomcat就會將其變成響應(yīng)文本的格式發(fā)送給瀏覽器焕盟。

Java Servlet API 是Servlet容器(tomcat)和servlet之間的接口秋秤,它定義了serlvet的各種方法,還定義了Servlet容器傳送給Servlet的對象類脚翘,其中最重要的就是ServletRequest和ServletResponse灼卢。

所以說我們在編寫servlet時,需要實(shí)現(xiàn)Servlet接口来农,按照其規(guī)范進(jìn)行操作鞋真。

Servlet執(zhí)行過程

在瀏覽器的地址欄輸入:http://ip:port/appNames/servlet

1)通過瀏覽器和ip:port和這個服務(wù)器建立連接。
  2) 瀏覽器會生成一個請求數(shù)據(jù)包(路徑appNames/servlet)向服務(wù)器發(fā)送請求沃于。
  3) 服務(wù)器收到請求數(shù)據(jù)包涩咖,分析請求資源路徑做精準(zhǔn)定位,通過請求的appName查找webapps文件下面的appName做匹配繁莹,匹配上了需要獲取web.xml中的servlet(mapping)檩互。 
  4) 服務(wù)器創(chuàng)建兩個對象:
    第一個對象:請求對象咨演,該對象實(shí)現(xiàn)了HttpServletRequest接口闸昨,服務(wù)器會將請求數(shù)據(jù)包中的數(shù)據(jù)解析出來,存儲在該對象里。這樣做的好處是沒有必要理解http協(xié)議雪标,只需要讀取request零院。
    第二個對象:響應(yīng)對象,實(shí)現(xiàn)了HttpServletResponse接口村刨,作用是servlet處理完成后的結(jié)果可以存放到該對象上告抄,然后服務(wù)器依據(jù)該對象的數(shù)據(jù)生成響應(yīng)數(shù)據(jù)包。
  5) servlet在執(zhí)行servlet()方法時嵌牺,可以通過request獲取請求數(shù)據(jù)打洼,也可以將處理結(jié)果存放到response上。然后服務(wù)器與響應(yīng)對象直接形成一個默契逆粹,生成一個響應(yīng)數(shù)據(jù)包給瀏覽器募疮。
  6)瀏覽器解析服務(wù)器返回的響應(yīng)數(shù)據(jù)包,生成響應(yīng)的結(jié)果僻弹。

image

Servlet訪問的過程:
Http請求---->web.xml--------> url -pattern----->servlet-name----->servlet-class-----> QuickStratServlet(對應(yīng)的Class文件)

Servlet的生命周期

Servlet生命周期可分為5個步驟

  1. 加載Servlet阿浓。當(dāng)Tomcat第一次訪問Servlet的時候,Tomcat會負(fù)責(zé)創(chuàng)建Servlet的實(shí)例
  2. 初始化蹋绽。當(dāng)Servlet被實(shí)例化后芭毙,Tomcat會調(diào)用init()方法初始化這個對象
  3. 處理服務(wù)筋蓖。當(dāng)瀏覽器訪問Servlet的時候,Servlet 會調(diào)用service()方法處理請求
  4. 銷毀退敦。當(dāng)Tomcat關(guān)閉時或者檢測到Servlet要從Tomcat刪除的時候會自動調(diào)用destroy()方法粘咖,讓該實(shí)例釋放掉所占的資源。一個Servlet如果長時間不被使用的話侈百,也會被Tomcat自動銷毀
  5. 卸載瓮下。當(dāng)Servlet調(diào)用完destroy()方法后,等待垃圾回收钝域。如果有需要再次使用這個Servlet讽坏,會重新調(diào)用init()方法進(jìn)行初始化操作。

簡單總結(jié):只要訪問Servlet网梢,service()就會被調(diào)用震缭。init()只有第一次訪問Servlet的時候才會被調(diào)用。
destroy()只有在Tomcat關(guān)閉的時候才會被調(diào)用战虏。

Servlet的配置

使用配置文件
  1. 寫Servlet類
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }
}
  1. 在web.xml中配置Servlet


    image.png
使用springboot
  1. 寫servlet類
  2. 在springboot啟動類配置
@SpringBootApplication
public class ServletApp {

    @Bean
    public ServletRegistrationBean MyServlet(){
        return new ServletRegistrationBean(new MyServlet(),"/myserv/*");
    }

    public static void main(String[] args){
        SpringApplication.run(ServletApp.class, args);
    }
}

Servlet細(xì)節(jié)

  • Servlet的url匹配順序

當(dāng)一個請求發(fā)送到servlet容器的時候拣宰,容器先會將請求的url減去當(dāng)前應(yīng)用上下文的路徑作為servlet的映射url,比如我訪問的是http://localhost/hiway/user/aaa.html烦感,我的應(yīng)用上下文是hiway巡社,容器會將http://localhost/hiway去掉,剩下的/user/aaa.html部分拿來做servlet的映射匹配手趣。這個映射匹配過程是有順序的晌该,而且當(dāng)有一個servlet匹配成功以后,就不會去理會剩下的servlet了绿渣。其匹配規(guī)則和順序如下:

  1. 精確路徑匹配朝群。例子:比如servletA 的url-pattern為 /test,servletB的url-pattern為 /* 中符,這個時候姜胖,如果我訪問的url為http://localhost/test ,這個時候容器就會先進(jìn)行精確路徑匹配淀散,發(fā)現(xiàn)/test正好被servletA精確匹配右莱,那么就去調(diào)用servletA,也不會去理會其他的servlet了档插。
  2. 最長路徑匹配慢蜓。例子:servletA的url-pattern為/test/,而servletB的url-pattern為/test/a/郭膛,此時訪問http://localhost/test/a時晨抡,容器會選擇路徑最長的servlet來匹配,也就是這里的servletB。
  3. 擴(kuò)展匹配耘柱。如果url最后一段包含擴(kuò)展圆雁,容器將會根據(jù)擴(kuò)展選擇合適的servlet。例子:servletA的url-pattern:*.action
  4. 最后帆谍,如果前面三條規(guī)則都沒有找到一個servlet,容器會根據(jù)url選擇對應(yīng)的請求資源轴咱。如果應(yīng)用定義了一個default servlet汛蝙,則容器會將請求丟給default servlet
  • Servlet是單例的嗎

在Servlet規(guī)范中,對于Servlet單例與多例定義如下:

“Deployment Descriptor”, controls how the servlet container provides instances of the servlet.For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.

上面規(guī)范提到:
如果一個Servlet沒有被部署在分布式的環(huán)境中朴肺,一般web.xml中聲明的一個Servlet只對應(yīng)一個實(shí)例窖剑。
而如果一個Servlet實(shí)現(xiàn)了SingleThreadModel接口,就會被初始化多個實(shí)例戈稿。默認(rèn)20個

所以個人理解Servlet不算單例西土,只是容器讓它只實(shí)例化一次,變現(xiàn)出來的是單例的效果而已

  • 如何開發(fā)線程安全的Servlet
  1. 實(shí)現(xiàn) SingleThreadModel 接口
  2. 使用synchronized同步對共享數(shù)據(jù)的操作
  3. 避免使用實(shí)例變量

對上面的三種方法進(jìn)行測試鞍盗,可以表明用它們都能設(shè)計(jì)出線程安全的Servlet程序需了。但是,如果一個Servlet實(shí)現(xiàn)了SingleThreadModel接口般甲,Servlet引擎將為每個新的請求創(chuàng)建一個單獨(dú)的Servlet實(shí)例肋乍,這將引起大量的系統(tǒng)開銷。SingleThreadModel在Servlet2.4中已不再提倡使用敷存;同樣如果在程序中使用同步來保護(hù)要使用的共享的數(shù)據(jù)墓造,也會使系統(tǒng)的性能大大下降。這是因?yàn)楸煌降拇a塊在同一時刻只能有一個線程執(zhí)行它锚烦,使得其同時處理客戶請求的吞吐量降低觅闽,而且很多客戶處于阻塞狀態(tài)。另外為保證主存內(nèi)容和線程的工作內(nèi)存中的數(shù)據(jù)的一致性涮俄,要頻繁地刷新緩存,這也會大大地影響系統(tǒng)的性能蛉拙。所以在實(shí)際的開發(fā)中也應(yīng)避免或最小化 Servlet 中的同步代碼;在Serlet中避免使用實(shí)例變量是保證Servlet線程安全的最佳選擇禽拔。從Java 內(nèi)存模型也可以知道刘离,方法中的臨時變量是在棧上分配空間,而且每個線程都有自己私有的椂闷埽空間硫惕,所以它們不會影響線程的安全

學(xué)習(xí)資料:http://lixh1986.iteye.com/blog/2355692

  • Servlet的<load-on-startup>

在servlet的配置當(dāng)中,

<load-on-startup>1</load-on-startup>

的含義是:
標(biāo)記容器是否在啟動的時候就加載這個servlet野来。當(dāng)值為0或者大于0時恼除,表示容器在應(yīng)用啟動時就加載這個servlet;當(dāng)是一個負(fù)數(shù)時或者沒有指定時,則指示容器在該servlet被選擇時才加載豁辉。正數(shù)的值越小令野,啟動該servlet的優(yōu)先級越高。
配置load-on-startup后徽级,servlet在startup后立即加載气破,但只是調(diào)用servlet的init()方法,用以初始化該servlet相關(guān)的資源餐抢。初始化成功后现使,該servlet可響應(yīng)web請求;如未配置load-on-startup旷痕,容器一般在第一次響應(yīng)web請求時碳锈,會先檢測該servlet是否初始化,如未初始化欺抗,則調(diào)用servlet的init()先初始化售碳,初始化成功后,再響應(yīng)請求绞呈。

  • 缺省default Servlet

可以將url-pattern 配置一個/贸人,代表該servlet是缺省的servlet。什么是缺省的servlet佃声?
當(dāng)你訪問資源地址所有的servlet都不匹配時灸姊,缺省的servlet賦值處理。其實(shí)秉溉,web應(yīng)用中所有的資源的響應(yīng)都是servlet負(fù)責(zé)力惯,包括靜態(tài)資源(html頁面)。(有配置缺省的servlet召嘶,無法訪問到靜態(tài)資源父晶。)

學(xué)習(xí)資料:https://www.cnblogs.com/zhangyinhua/p/7625851.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弄跌,隨后出現(xiàn)的幾起案子甲喝,更是在濱河造成了極大的恐慌,老刑警劉巖铛只,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埠胖,死亡現(xiàn)場離奇詭異,居然都是意外死亡淳玩,警方通過查閱死者的電腦和手機(jī)直撤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜕着,“玉大人谋竖,你說我怎么就攤上這事红柱。” “怎么了蓖乘?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵锤悄,是天一觀的道長。 經(jīng)常有香客問我嘉抒,道長零聚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任些侍,我火速辦了婚禮握牧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娩梨。我一直安慰自己,他們只是感情好览徒,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布狈定。 她就那樣靜靜地躺著,像睡著了一般习蓬。 火紅的嫁衣襯著肌膚如雪纽什。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天躲叼,我揣著相機(jī)與錄音芦缰,去河邊找鬼。 笑死枫慷,一個胖子當(dāng)著我的面吹牛让蕾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播或听,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼探孝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了誉裆?” 一聲冷哼從身側(cè)響起顿颅,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎足丢,沒想到半個月后粱腻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斩跌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年绍些,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耀鸦。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡遇革,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萝快,我是刑警寧澤锻霎,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站揪漩,受9級特大地震影響旋恼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奄容,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一冰更、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧昂勒,春花似錦蜀细、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至塘娶,卻和暖如春归斤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刁岸。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工脏里, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虹曙。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓迫横,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酝碳。 傳聞我的和親對象是個殘疾皇子员淫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)击敌,斷路器介返,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,315評論 1 92
  • 1徘公、Filter的功能 filter功能,它使用戶可以改變一個 request和修改一個response. Fil...
    JAVA架構(gòu)師的圈子閱讀 585評論 0 0
  • 又是一場風(fēng) 從西方飄然而至 印象的春天哮针,東風(fēng)主宰 離別將近的日子 本該積蓄淚水关面,為了揮手時涌動 而現(xiàn)實(shí)總有一些障礙...
    裝在盒子里的泥鰍閱讀 149評論 0 0
  • 從小到大坦袍,我是個不愛張揚(yáng)的女孩,這好像是我的優(yōu)點(diǎn)等太,但漸漸地捂齐,發(fā)現(xiàn)它同時成了我最大的缺點(diǎn)。上課靜靜坐著缩抡,想什么也不去...
    王紫燕閱讀 190評論 0 5