天天看點

【java web】Servlet生命周期

在Java web中 Servlet 是根基。雖然工作中幾乎沒人再去寫Servlet了,架構為我們完成了這些工作。我們隻要專注于業務邏輯的實作。但是了解Servlet還是很有必要的。

1. Servlet的架構圖

【java web】Servlet生命周期

Servlet Container 指的是Tomcat這樣可以處理Servlet的伺服器。

2. Servlet是怎麼處理請求的?

做一個實驗,首先用Eclipse建立一個項目,如下

【java web】Servlet生命周期

需要我們自己編輯的有四個檔案

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="LoginServlet" method="get">
<label>使用者名</label>
<input name="username" type="text">
<br/>
<label>密碼</label>
<input name="password" type="password">
<input type="submit" value="登陸">
</form>

</body>
</html>      

doGet.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Get Success
</body>
</html>      

doPost.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
post success
</body>
</html>      

着重講一下LoginServlet.java, 建立一個Servlet, Eclipse會預設生成doGet 和 doPost方法。 init()方法和destory()方法是從HttpServlet繼承的, 我們隻做一個列印,直接調用HttpServlet的實作,這樣不會影響Servlet的運作

package com.yeyeck.controller;

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;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
    
    
    @Override
    public void init() throws ServletException {
        System.out.println("init() worked");
        super.init();
    }
    
    
    @Override
    public void destroy() {
        System.out.println("destroy() worked");
        super.destroy();
    }
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service() worked");
        super.service(req, resp);
    }
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet() worked");
        System.out.println("hash: " + this.hashCode());
        // TODO Auto-generated method stub
        System.out.println(request.getParameter("username"));
        System.out.println(request.getParameter("password"));
        response.sendRedirect("doGet.jsp");
//        response.getWriter().append("登陸成功");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
        System.out.println("doPost() worked");
        System.out.println("hash: " + this.hashCode());
        System.out.println(request.getParameter("username"));
        System.out.println(request.getParameter("password"));
        response.sendRedirect("doPost.jsp");
    }

}      

把項目部署到Tomcat跑起來,浏覽器鍵入通路位址

【java web】Servlet生命周期

會看到

【java web】Servlet生命周期

右鍵檢查,會看到表單現在的送出方式是get

【java web】Servlet生命周期
【java web】Servlet生命周期

 在輸入框内随便輸入一些資料,送出。觀察Eclipse控制台

【java web】Servlet生命周期

頁面跳轉到

【java web】Servlet生命周期

從控制台輸出,我們可以看到,這次get請求,依次調用了 init()、service()、 doGet()方法

回到index,再請求一次,控制台顯示

【java web】Servlet生命周期

可以發現,第二次請求,隻調用了 service() 和 doGet() 方法, 并且兩次列印的hash值是一樣的

我們再把index.jsp的表單改成post方式送出, ctrl+save

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="LoginServlet" method="post">
<label>使用者名</label>
<input name="username" type="text">
<br/>
<label>密碼</label>
<input name="password" type="password">
<input type="submit" value="登陸">
</form>

</body>
</html>      

回到首頁右鍵檢查, 此時的請求方式已經變為post

【java web】Servlet生命周期

随便輸入一些資料,送出。控制台顯示如下

【java web】Servlet生命周期

發現又多了一些列印,這次post請求調用了 service() 和 doPost() 方法, 而且列印的hash值依然沒有變。

關閉tomcat

【java web】Servlet生命周期

回到console, 顯示如下

【java web】Servlet生命周期

發現調用了destory()方法

以上過程表明

  1. Hash值始終沒變

  2. 隻有第一次請求的時候調用了 init() 方法

  3. 每次請求都調用了service() 方法

  4. 調用完service() 方法後,會根據資料送出的方式,選擇調用doPost() 或者 doGet() 方法

  5. Tomcat關閉的時候,會調用destroy()方法。

是以

  1. servlet是單例的

  2. init()方法隻會在第一次請求這個Servlet的時候調用, Servlet()的生命周期開始

  3. 每次請求都會調用service() 方法, 并且在調用完service() 方法後,會根據資料送出的方式,選擇調用doPost() 或者 doGet() 方法

  5. 僅在tomcat關閉的時候調用destroy()方法, Servlet的生命周期結束

繼續閱讀