1. 程式人生 > 其它 >【JavaWeb-Servlet】筆記(1)--- Servlet規範;Servlet介面實現類;Servlet物件生命週期;HttpServletResponse/HttpServletRequest;請求物件和響應物件生命週期

【JavaWeb-Servlet】筆記(1)--- Servlet規範;Servlet介面實現類;Servlet物件生命週期;HttpServletResponse/HttpServletRequest;請求物件和響應物件生命週期

前言:


Servlet規範介紹:

1.servlet 規範來自於 JAVAEE 規範中的一種。

2.作用:

1)指定【動態資原始檔】開發步驟。

2)指定Http伺服器呼叫動態資原始檔規則。

3)指定Http伺服器管理動態資原始檔例項物件規則。

 

Servlet介面實現類:

1.Servlet介面來自於Servlet規範下的一個介面,這個介面存在於Http伺服器提供的 jar 包中。

2.Tomcat伺服器(也是一種Http伺服器)下的lib檔案中有一個 servlet-api.jar 來存放 Servlet 介面(javax.servlet.Servlet介面)。

3.Servlet規範認為,Http伺服器能呼叫的【動態資原始檔】必須是一個Servlet介面實現類。

 

Servlet介面實現類開發步驟:


第一步:建立一個Java類繼承 HttpServlet父類,使之成為一個Servlet介面實現類。

       提問:為什麼不直接建立一個Java類實現Servlet介面?

                 因為Servlet介面中除了doGet()和doPost(),還有很多抽象方法,但是非抽象類實現介面,必須要重寫介面中的所有方法,而我們需要使用的方法只有doGet()和doPost(),這樣就大大增加了我們寫程式碼的工作量。而通過 HttpServlet 抽象類(作為一個“中介”)來實現Servlet介面,將我們需要使用的兩個方法保留,而將Servlet中我們不需要的方法重寫為非抽象方法,這樣我們再建立一個Java類來繼承HttpSerlet抽象類,既得到了我們需要用的兩個方法,又不需要重寫介面中的其他方法,so nice ~ ~

 

第二步:重寫 HttpServlet 父類兩個方法,doGet( )或doPost( )。

package com.burnyouth.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class OneServlet extends HttpServlet {
    //執行doGet()還是doPost()取決於客戶端伺服器發過來的請求
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("OneSelect類針對瀏覽器傳送GET請求方式處理");
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("OneSelect類針對瀏覽器傳送POST請求方式處理");
    }
}

 

第三步:將 Servlet 介面實現類資訊【註冊】到Tomcat伺服器。

檔案路徑:【網站】--->【web】--->【WEB-INF】--->web.xml

<!--將Servlet介面實現類的路徑地址交給Tomcat-->
<servlet>
    <!--宣告一個變數儲存servlet介面實現類路徑-->
    <servlet-name>mm</servlet-name>
    <!--宣告servlet介面實現類路徑-->
    <servlet-class>com.burnyouth.controller.OneServlet</servlet-class>
</servlet>

<!--為了降低使用者訪問Servlet介面實現類難度,需要設定簡短請求別名-->
<servlet-mapping>
    <servlet-name>mm</servlet-name>
    <!--設定簡短請求別名,別名在書寫時必須以"/"為開頭-->
    <url-pattern>/one</url-pattern> 
</servlet-mapping>

如果此時使用者通過瀏覽器向 Tomcat 索要 OneServlet 時的地址:  http://localhost:8080/myWeb/one

 

Servlet物件生命週期:


1.網站中所有的Servlet介面實現類的例項物件,只能由Http伺服器負責建立。開發人員不能手動建立Servlet介面實現類的例項物件,所以我們以後幾乎不需要再寫 main方法了。

2.預設的情況下,Http伺服器只有在接收到對於當前 Servlet 介面實現類第一次請求時才會自動建立這個Servlet介面實現類的例項物件。

   如何使 Http 伺服器在啟動時自動建立某個Servlet介面實現類的例項物件?

<servlet>
    <!--宣告一個變數儲存servlet介面實現類類路徑-->
    <servlet-name>oneServlet</servlet-name> 
    <servlet-class>com.burnyouth.controller.OneServlet</servlet-class>
    <!--填寫一個大於0的整數即可-->
    <load-on-startup>1</load-on-startup>
</servlet>

 

3.在Http伺服器執行期間,一個Servlet介面實現類只能被創建出一個例項物件。

4.在Http伺服器關閉時刻,自動將網站中所有的Servlet物件進行銷燬。

 

HttpServletResponse介面:


1.介紹:

1)HttpServletResponse 介面來自於Servlet規範中,在Tomcat中存在servlet-api.jar。

2)HttpServletResponse 介面實現類由Http伺服器負責提供。

3)HttpServletResponse 介面負責將 doGet/doPost 方法的執行結果寫入到【響應體】中交給瀏覽器。

4)開發人員習慣於將 HttpServletResponse 介面修飾的物件稱為【響應物件】。

2.主要功能:

1) 將執行結果以二進位制形式寫入到【響應體】

package com.burnyouth.controller;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;


//演示 HttpServletResponse介面的功能一:
public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        //假設result為執行結果
        String result = "Hello World";

        //通過響應物件,向Tomcat索要輸出流
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //通過輸出流,將執行結果以二進位制形式寫入到響應體
        out.write(result);
    }
}

注意:

out.writer方法可以將【字元】,【字串】,【ASCII碼】寫入到響應體,所以實際開發過程中,都是通過out.print()將真實資料寫入到響應體(防止數字被以ASCII碼的方式解讀等)。

 

2) 設定響應頭中[content-type]屬性值,從而控制瀏覽器使用對應編譯器將響應體二進位制資料編譯為【文字,圖片,視訊,命令】。

package com.burnyouth.controller;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        //既有文字資訊又有HTML標籤命令
        String result="Java<br/>HTML<br/>";

        //在得到輸出流之前,設定響應頭content-type屬性(使瀏覽器用正確的編譯器解讀資料)
        response.setContentType("text/html;charset=utf-8");

        //向Tomcat索要輸出流
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //通過輸出流將結果寫入到響應體
        out.print(result);
    }
}

注意:

在預設的情況下,content-type屬性的值為“text”,此時瀏覽器將會採用【文字編譯器】對響應體二進位制資料進行解析。

所以一定要在得到輸出流之前,通過響應物件對響應頭中content-type屬性進行重新賦值,令瀏覽器使用正確的編譯器解讀資料。

 

3) 設定響應頭中【location】屬性,將一個請求地址賦值給 location,從而控制瀏覽器向指定伺服器傳送請求。

package com.burnyouth.controller;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        String result = "http://www.baidu.com";

        //通過響應物件,將地址賦值給響應頭中location屬性
        try {
            //瀏覽器在接收到響應包之後,如果發現響應頭中存在location屬性,自動通過位址列向location指定網站傳送請求
            response.sendRedirect(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

HttpServletRequest介面:


1.介紹:

1)HttpServletRequest 介面來自於Servlet規範中,在Tomcat中存在servlet-api.jar。

2)HttpServletRequest 介面實現類由Http伺服器負責提供。

3)HttpServletRequest 介面負責在doGet/doPost方法執行時讀取Http請求協議包中資訊。

4)開發人員習慣於將 HttpServletRequest 介面修飾的物件稱為【請求物件】。


2.作用:

1)可以讀取Http請求協議包中【請求行】資訊。

   知識小貼士:     

           URI:資原始檔精準定位地址(請求行並沒有URI屬性),實際上URI就是URL中擷取的一個字串,URI(格式為:/網站名/資原始檔名)用於讓Http伺服器對被訪問的資原始檔進行定位。

package com.burnyouth.controller;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        //通過請求物件,讀取【請求行】中【url】資訊

        String url = request.getRequestURL().toString();

        //通過請求物件,讀取【請求行】中【method】資訊
        String method = request.getMethod();

        //通過請求物件,讀取【請求行】中URI資訊
        String uri =  request.getRequestURI();// substring

        System.out.println("URL: "+url);
        System.out.println("method: "+method);
        System.out.println("URI:"+uri);
    }
}

 

控制檯:

 

2)可以讀取儲存在Http請求協議包中【請求頭】或則【請求體】中的請求引數資訊。

package com.burnyouth.controller;

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.util.Enumeration;

public class OneServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        //通過請求物件獲得【請求頭】中【所有請求引數名】(將所有請求引數名稱儲存到一個列舉物件進行返回)
        Enumeration paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();

            //通過請求物件讀取指定的請求引數的值
            String value = request.getParameter(paramName);
            System.out.println("請求引數名 " + paramName + "--->請求引數值 " + value);
        }
    }
}

 

3)可以代替瀏覽器向Http伺服器申請資原始檔呼叫(後面再曰)

 

請求物件和響應物件生命週期:


1.在Http伺服器接收到瀏覽器傳送的【Http請求協議包】之後,自動為當前的【Http請求協議包】生成一個【請求物件】和一個【響應物件】。

2.在Http伺服器呼叫doGet/doPost方法時,負責將【請求物件】和【響應物件】,作為實參傳遞到方法,確保doGet/doPost正確執行。

3.在Http伺服器準備推送Http響應協議包之前,負責將本次請求關聯的【請求物件】和【響應物件】銷燬。

4、換一種說法:

【請求物件】和【響應物件】生命週期貫穿一次請求的處理過程中。
【請求物件】和【響應物件】相當於使用者在服務端的代言人。

5、請求物件和響應物件生命週期圖示: