day48_HTTP響應消息丶 Response對象丶ServletContext對象

HTTP協議:響應消息

  • 請求消息:客戶端發送給服務器端的數據
  • 響應消息:服務器端發送給客戶端的數據

響應消息數據格式:

  • 響應消息格式由響應行丶響應頭丶響應空行丶響應體組成。

1. 響應行

由下面幾部分組成:

  • 協議/版本
  • 響應狀態碼
  • 狀態碼描述

2. 響應頭:

  • 格式:頭名稱: 值

常見的響應頭:

  • Content-Type:服務器告訴客戶端本次響應體數據格式以及編碼格式
  • Content-disposition:服務器告訴客戶端以什麼格式打開響應體數據值 in-line:默認值,在當前頁面內打開丶attachment;filename=xxx:以附件形式打開響應體。文件下載使用這個值

3. 響應空行就是一個空行

4. 響應體:傳輸的真實數據

常用的響應狀態碼下所示

1xx:指示信息–表示請求已接收,繼續處理。

  • 100 http1.1協議中的首部接收成功,可以繼續發送body了。

2xx:成功–表示請求已被成功接收、理解、接受。

  • 200(成功)用瀏覽器打開一個網頁,正常情況下都會返回200HTTP狀態碼。

3xx重定向(URL跳轉)–要完成請求必須進行更進一步的操作。

  • 300(多種選擇)下載一部片,服務器有 avi、mp4 等格式。
  • 301(永久移動)請求的網頁已永久移動到新位置,自動將請求者轉到新位置。
  • 304 (頁面未修改) :按F5刷新(第二次訪問)。

4xx:客戶端錯誤–請求有語法錯誤或請求無法實現。

  • 400(錯誤請求)服務器不理解請求的語法。
  • 401(未授權)沒有攜帶認證信息或攜帶了錯誤的認證信息,而沒有通過認證。(未登錄時)
  • 403(禁止)攜帶了正確的認證信息,服務器認爲該用戶對該資源無權訪問。(https輸成了http)
  • 404(未找到)請求的內容不存在。
  • 405:請求方式沒有對應的doXxx方法

5xx:服務器端錯誤–服務器未能實現合法的請求。

  • 500(服務器內部錯誤)服務器自己出現錯誤。
  • 502(網關錯誤)服務器作爲網關或代理,從上游服務器收到無效響應。
  • 503(服務器不可用)服務器超載或停機維護不可用。

Response對象

功能:設置響應消息

1. 設置響應行

  • 設置狀態碼:使用方法setStatus(int sc) 

 2. 設置響應頭:

  • 使用方法setHeader(String name, String value) 

3. 設置響應體:

步驟如下:

  1. 獲取輸出流。獲取字符輸出流:PrintWriter getWriter() 或者 字節輸出流:ServletOutputStream getOutputStream()
  2. 使用輸出流,將數據輸出到客戶端瀏覽器

重定向

  • 重定向是一種資源跳轉的方式

代碼演示

package com.wrg.sendRedirect;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ServletDemo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        System.out.println("1111111111");
        /*
        重定向方式一:
             //1. 設置狀態碼爲302
             response.setStatus(302);
             //2.設置響應頭location
           response.setHeader("location","/ServletDemo02");
         */
        //方式二

        //簡單的重定向方法,參數是虛擬目錄+要定向的目的地
        response.sendRedirect("ServletDemo02");
        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        doPost(request, response);
    }
}

 重定向的特點:redirect

  • 地址欄發生變化
  • 重定向可以訪問其他站點(服務器)的資源
  • 重定向是兩次請求。不能使用request對象來共享數據

轉發的特點:forward

  • 轉發地址欄路徑不變
  • 轉發只能訪問當前服務器下的資源
  • 轉發是一次請求,可以使用request對象來共享數據

web路徑寫法:

路徑分類

相對路徑:通過相對路徑不可以確定唯一資源 如:./index.html。不以/開頭,以.開頭路徑

  • 規則:找到當前資源和目標資源之間的相對位置關係
  •  * ./:當前目錄
  • ../:後退一級目錄

絕對路徑:通過絕對路徑可以確定唯一資源 如:http://localhost/day15/responseDemo2 可以簡化爲 /day15/responseDemo2 以/開頭的路徑

  • 規則:判斷定義的路徑是給誰用的?判斷請求將來從哪兒發出
  • 給客戶端瀏覽器使用:需要加虛擬目錄(項目的訪問路徑)。建議虛擬目錄動態獲取:request.getContextPath()。判斷請求從哪發出,例如:<a> , <form> 重定向...
  • 給服務器使用:不需要加虛擬目錄,例如:轉發路徑

服務器輸出字符數據到瀏覽器

步驟:

  1. 獲取字符輸出流
  2. 輸出數據

注意:

亂碼問題:編碼和解碼不一致

解決方式:

  • PrintWriter pw = response.getWriter();獲取的流的默認編碼是ISO-8859-1
  • 設置該流的默認編碼
  • 告訴瀏覽器響應體使用的編碼

簡單的形式,設置編碼,是在獲取流之前設置

  • response.setContentType("text/html;charset=utf-8");

代碼演示

@WebServlet("/ServletDemo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        System.out.println("1111111111");

        /*
        獲取流對象之前,設置流的默認編碼:ISO-8859-1 設置爲:GBK
        response.setCharacterEncoding("utf-8");

        告訴瀏覽器,服務器發送的消息體數據的編碼。建議瀏覽器使用該編碼解碼
        response.setHeader("content-type","text/html;charset=utf-8");
         */

        
        //方式二:簡單的形式,設置編碼
        response.setContentType("text/html;charset=utf-8");
        //1.獲取字符輸出流
        PrintWriter pw = response.getWriter();
        //2.輸出數據
        //pw.write("<h1>hello response</h1>");
        pw.write("你好啊啊啊 response");
    }

服務器輸出字節數據到瀏覽器和輸出字符數據一模一樣。唯一的區別就是獲取的輸出的流不同。

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
	//告訴瀏覽器,服務端使用什麼字符集編碼
        response.setContentType("text/html;charset=utf-8");

        //1.獲取字節輸出流
        ServletOutputStream sos = response.getOutputStream();
        //2.輸出數據
        sos.write("你好".getBytes("utf-8"));
    }

驗證碼案例

public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {


        int width = 100;
        int height = 50;

        //1.創建一對象,在內存中圖片(驗證碼圖片對象)
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);


        //2.美化圖片
        //2.1 填充背景色
        Graphics g = image.getGraphics();//畫筆對象
        g.setColor(Color.PINK);//設置畫筆顏色
        g.fillRect(0,0,width,height);

        //2.2畫邊框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width - 1,height - 1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成隨機角標
        Random ran = new Random();

        for (int i = 1; i <= 4; i++) {
            int index = ran.nextInt(str.length());
            //獲取字符
            char ch = str.charAt(index);//隨機字符
            //2.3寫驗證碼
            g.drawString(ch+"",width/5*i,height/2);
        }


        //2.4畫干擾線
        g.setColor(Color.GREEN);

        //隨機生成座標點

        for (int i = 0; i < 10; i++) {
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }


        //3.將圖片輸出到頁面展示
        ImageIO.write(image,"jpg",response.getOutputStream());


    }

點擊換一張圖片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
        /*
            分析:
                點擊超鏈接或者圖片,需要換一張
                1.給超鏈接和圖片綁定單擊事件

                2.重新設置圖片的src屬性值

         */
    window.onload = function(){
        //1.獲取圖片對象
        var img = document.getElementById("checkCode");
        //2.綁定單擊事件
        img.onclick = function(){
            //加時間戳
            var date = new Date().getTime();

            img.src = "/day15/checkCodeServlet?"+date;
        }

    }


    </script>


</head>
<body>


    <img id="checkCode" src="/day15/checkCodeServlet" />

    <a id="change" href="">看不清換一張?</a>

</body>
</html>

ServletContext對象:

  • 概念:代表整個web應用,可以和程序的容器(服務器)來通信。

獲取ServletContext對象:

  • 通過request對象獲取 方法 request.getServletContext();
  • 通過HttpServlet獲取  方法this.getServletContext();

ServletContext對象功能

1:獲取MIME類型:

  • MIME類型:在互聯網通信過程中定義的一種文件數據類型
  • MIME的組成結構非常簡單;由類型與子類型兩個字符串中間用'/'分隔而組成。不允許空格存在。type 表示可以被分多個子類獨立類別。subtype 表示細分後的每個類型。

2. ServletContext是個域對象:共享數據

  • 由於一個web應用中的所有Servlet共享同一個ServletContext對象:因此Servlet對象之間可以通過ServletContext來是實現通訊。ServletContext對象通常也被稱爲context域對象。

3. 獲取文件的真實(服務器)路徑

 可以搜索當前工程目錄下面的資源文件

  • getServletContext().getRealPath(path),根據相對路徑獲取服務器上資源的絕對路徑
  • getServletContext().getResourceAsStream(path),根據相對路徑獲取服務器上資源的輸入字節流
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章