Java中Servlet的生命周期詳解
Web基礎(chǔ)和HTTP協(xié)議
┌─────────┐ ┌─────────┐ │?????????│ │O ???????│ ├─────────┤ ├─────────┤ │?????????│ │ │ ├─────────┤ │ │ │?????????│ └─────────┘ └─────────┘ │ request 1 │ │─────────────────────>│ │ request 2 │ │─────────────────────>│ │ response 1 │ │<─────────────────────│ │ request 3 │ │─────────────────────>│ │ response 3 │ │<─────────────────────│ │ response 2 │ │<─────────────────────│ ▼ ▼
我們注意到HTTP協(xié)議是一個(gè)請(qǐng)求-響應(yīng)協(xié)議,它總是發(fā)送一個(gè)請(qǐng)求,然后接收一個(gè)響應(yīng)。能不能一次性發(fā)送多個(gè)請(qǐng)求,然后再接收多個(gè)響應(yīng)呢?HTTP 2.0
可以支持瀏覽器同時(shí)發(fā)出多個(gè)請(qǐng)求,但每個(gè)請(qǐng)求需要唯一標(biāo)識(shí),服務(wù)器可以不按請(qǐng)求的順序返回多個(gè)響應(yīng),由瀏覽器自己把收到的響應(yīng)和請(qǐng)求對(duì)應(yīng)起來??梢?,HTTP 2.0
進(jìn)一步提高了傳輸效率,因?yàn)闉g覽器發(fā)出一個(gè)請(qǐng)求后,不必等待響應(yīng),就可以繼續(xù)發(fā)下一個(gè)請(qǐng)求。
HTTP 3.0
為了進(jìn)一步提高速度,將拋棄TCP
協(xié)議,改為使用無需創(chuàng)建連接的UDP
協(xié)議,目前HTTP 3.0
仍然處于實(shí)驗(yàn)推廣階段。
什么是Servlet
在JavaEE
平臺(tái)上,處理TCP
連接,解析HTTP
協(xié)議這些底層工作統(tǒng)統(tǒng)扔給現(xiàn)成的Web
服務(wù)器去做,我們只需要把自己的應(yīng)用程序跑在Web
服務(wù)器上。為了實(shí)現(xiàn)這一目的,JavaEE
提供了Servlet
API
,我們使用Servlet API
編寫自己的Servlet
來處理HTTP
請(qǐng)求,Web
服務(wù)器實(shí)現(xiàn)Servlet
API
接口,
實(shí)現(xiàn)底層功能.
// WebServlet注解表示這是一個(gè)Servlet,并映射到地址 hello.do @WebServlet(urlPatterns = "/hello.do") public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 設(shè)置響應(yīng)類型: resp.setContentType("text/html"); // 獲取輸出流: PrintWriter pw = resp.getWriter(); // 寫入響應(yīng): pw.write("<h1>Hello, world!</h1>"); // 最后不要忘記flush強(qiáng)制輸出: pw.flush(); } }
一個(gè)Servlet
總是繼承自HttpServlet
,然后覆寫doGet()
或doPost()
方法。注意到doGet()
方法傳入了HttpServletRequest
和HttpServletResponse
兩個(gè)對(duì)象,分別代表HTTP
請(qǐng)求和響應(yīng)。我們使用Servlet API
時(shí),并不直接與底層TCP
交互,也不需要解析HTTP
協(xié)議,因?yàn)?code>HttpServletRequest和HttpServletResponse
就已經(jīng)封裝好了請(qǐng)求和響應(yīng)。以發(fā)送響應(yīng)為例,我們只需要設(shè)置正確的響應(yīng)類型,然后獲取PrintWriter
,寫入響應(yīng)即可。
而這樣的一個(gè)項(xiàng)目最終會(huì)打包成一個(gè)*.war
文件,運(yùn)行這個(gè)文件,需要使用支持Servlet
API
的Web容器(Web服務(wù)器)。
因此,我們首先要找一個(gè)支持Servlet API的Web服務(wù)器。
常用的服務(wù)器有:
- Tomcat:由Apache開發(fā)的開源免費(fèi)服務(wù)器;
- Jetty:由Eclipse開發(fā)的開源免費(fèi)服務(wù)器;
- GlassFish:一個(gè)開源的全功能JavaEE服務(wù)器。
Servlet的生命周期
在通過一個(gè)URL
路徑發(fā)起對(duì)一個(gè)Servlet
請(qǐng)求的過程中,其本質(zhì)是在調(diào)用執(zhí)行Servlet
實(shí)例的doXXX()
方法。該Servlet
實(shí)例創(chuàng)建和使用的過程,被稱為Servlet的生命周期。整個(gè)生命周期包括:實(shí)例化、初始化、服務(wù)、銷毀。
- 實(shí)例化:根據(jù)
Servlet
請(qǐng)求的路徑(例如:home.do
),查找該Servlet
的實(shí)例。如果實(shí)例不存在,則通過調(diào)用構(gòu)造方法,完成Servlet
實(shí)例的創(chuàng)建。 - 初始化:通過該
Servlet
的實(shí)例,調(diào)用init()
方法,執(zhí)行初始化的邏輯。 - 服務(wù):通過該
Servlet
的實(shí)例,調(diào)用service()
方法,如果子類沒有重寫該方法,則調(diào)用HttpServlet父類的service()
方法,在父類的該方法中進(jìn)行請(qǐng)求方式的判斷,如果是GET
請(qǐng)求,則調(diào)用doGet()
方法;如果是POST
請(qǐng)求,則調(diào)用doPost()
方法;
如果子類重寫doXXX()
方法,則調(diào)用子類重寫后的doXXX()
方法;
如果子類沒有重寫doXXX()
方法,則調(diào)用父類的doXXX()
方法,在父類的方法實(shí)現(xiàn)中,返回一個(gè)405
狀態(tài)碼的錯(cuò)誤頁面。
405狀態(tài)碼:代表請(qǐng)求的方式服務(wù)器不提供支持。
4.銷毀:服務(wù)器關(guān)閉或重啟時(shí),會(huì)銷毀所有的Servlet實(shí)例,會(huì)調(diào)用Servlet實(shí)例的destroy()
方法。
package com.my.hyz.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //@WebServlet("/home.do") public class HomeServlet extends HttpServlet { public HomeServlet() { System.out.println("實(shí)例化"); } @Override public void init() throws ServletException { System.out.println("初始化"); //super.init(); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("調(diào)用Service實(shí)例"); } @Override public void destroy() { System.out.println("銷毀咯!?。?!"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("哎呦get到了"+this.hashCode()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("哎呦post到了"); } }
到此這篇關(guān)于Java中Servlet的生命周期詳解的文章就介紹到這了,更多相關(guān)Java Servlet 生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合MyBatis-Plus3.1教程詳解
這篇文章主要介紹了SpringBoot整合MyBatis-Plus3.1詳細(xì)教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08深入分析Android系統(tǒng)中SparseArray的源碼
這篇文章主要介紹了深入分析Android系統(tǒng)中SparseArray的源碼,SparseArray為Java實(shí)現(xiàn),需要的朋友可以參考下2015-07-07SpringCloud Finchley+Spring Boot 2.0 集成Consul的方法示例(1.2版本)
這篇文章主要介紹了SpringCloud Finchley+Spring Boot 2.0 集成Consul的方法示例(1.2版本),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08java通過url讀取遠(yuǎn)程數(shù)據(jù)并保持到本地的實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了java通過url讀取遠(yuǎn)程數(shù)據(jù)并保持到本地的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07使用java批量寫入環(huán)境變量的實(shí)現(xiàn)
本文主要介紹了使用java批量寫入環(huán)境變量,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03