首頁 > 軟體

Java中Servlet的生命週期詳解

2022-08-22 22:00:03

Web基礎和HTTP協定

                       ┌─────────┐
┌─────────┐            │░░░░░░░░░│
│O ░░░░░░░│            ├─────────┤
├─────────┤            │░░░░░░░░░│
│         │            ├─────────┤
│         │            │░░░░░░░░░│
└─────────┘            └─────────┘
     │      request 1       │
     │─────────────────────>│
     │      request 2       │
     │─────────────────────>│
     │      response 1      │
     │<─────────────────────│
     │      request 3       │
     │─────────────────────>│
     │      response 3      │
     │<─────────────────────│
     │      response 2      │
     │<─────────────────────│
     ▼                      ▼

我們注意到HTTP協定是一個請求-響應協定,它總是傳送一個請求,然後接收一個響應。能不能一次性傳送多個請求,然後再接收多個響應呢?HTTP 2.0可以支援瀏覽器同時發出多個請求,但每個請求需要唯一標識,伺服器可以不按請求的順序返回多個響應,由瀏覽器自己把收到的響應和請求對應起來。可見,HTTP 2.0進一步提高了傳輸效率,因為瀏覽器發出一個請求後,不必等待響應,就可以繼續發下一個請求。

HTTP 3.0為了進一步提高速度,將拋棄TCP協定,改為使用無需建立連線的UDP協定,目前HTTP 3.0仍然處於實驗推廣階段。

什麼是Servlet

JavaEE平臺上,處理TCP連線,解析HTTP協定這些底層工作統統扔給現成的Web伺服器去做,我們只需要把自己的應用程式跑在Web伺服器上。為了實現這一目的,JavaEE提供了Servlet API,我們使用Servlet API編寫自己的Servlet來處理HTTP請求,Web伺服器實現Servlet API介面,

實現底層功能.

// WebServlet註解表示這是一個Servlet,並對映到地址 hello.do
@WebServlet(urlPatterns = "/hello.do")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 設定響應型別:
 
        resp.setContentType("text/html");
        // 獲取輸出流:
 
        PrintWriter pw = resp.getWriter();
        // 寫入響應:
 
        pw.write("<h1>Hello, world!</h1>");
        // 最後不要忘記flush強制輸出:
 
        pw.flush();
    }
}

一個Servlet總是繼承自HttpServlet,然後覆寫doGet()doPost()方法。注意到doGet()方法傳入了HttpServletRequestHttpServletResponse兩個物件,分別代表HTTP請求和響應。我們使用Servlet API時,並不直接與底層TCP互動,也不需要解析HTTP協定,因為HttpServletRequestHttpServletResponse就已經封裝好了請求和響應。以傳送響應為例,我們只需要設定正確的響應型別,然後獲取PrintWriter,寫入響應即可。

而這樣的一個專案最終會打包成一個*.war檔案,執行這個檔案,需要使用支援ServletAPI的Web容器(Web伺服器)。

因此,我們首先要找一個支援Servlet API的Web伺服器。

常用的伺服器有:

  • Tomcat:由Apache開發的開源免費伺服器;
  • Jetty:由Eclipse開發的開源免費伺服器;
  • GlassFish:一個開源的全功能JavaEE伺服器。

Servlet的生命週期

在通過一個URL路徑發起對一個Servlet請求的過程中,其本質是在呼叫執行Servlet範例的doXXX()方法。該Servlet範例建立和使用的過程,被稱為Servlet的生命週期。整個生命週期包括:範例化、初始化、服務、銷燬。

  • 範例化:根據Servlet請求的路徑(例如:home.do),查詢該Servlet範例。如果範例不存在,則通過呼叫構造方法,完成Servlet範例的建立。
  • 初始化:通過該Servlet範例,呼叫init()方法,執行初始化的邏輯。
  • 服務:通過該Servlet範例,呼叫service()方法,如果子類沒有重寫該方法,則呼叫HttpServlet父類別的service()方法,在父類別的該方法中進行請求方式的判斷,如果是GET請求,則呼叫doGet()方法;如果是POST請求,則呼叫doPost()方法;

如果子類重寫doXXX()方法,則呼叫子類重寫後的doXXX()方法;

如果子類沒有重寫doXXX()方法,則呼叫父類別的doXXX()方法,在父類別的方法實現中,返回一個405狀態碼的錯誤頁面。

405狀態碼:代表請求的方式伺服器不提供支援。

 4.銷燬:伺服器關閉或重啟時,會銷燬所有的Servlet範例,會呼叫Servlet範例的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("範例化");
	}
	@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("呼叫Service範例");
	}

	@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到了");
	}
}

到此這篇關於Java中Servlet的生命週期詳解的文章就介紹到這了,更多相關Java Servlet 生命週期內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com