HTTP&response響應&驗證碼&servletcontext

weixin_45636163發表於2020-11-07
1.   HTTP協議:響應訊息
2. Response物件
3. ServletContext物件

HTTP協議:

  1. 請求訊息:客戶端傳送給伺服器端的資料
    * 資料格式:
    1. 請求行
    2. 請求頭
    3. 請求空行
    4. 請求體
    1. 響應訊息:伺服器端傳送給客戶端的資料
      • 資料格式:

        1. 響應行

          1. 組成:協議/版本 響應狀態碼 狀態碼描述
          2. 響應狀態碼:伺服器告訴客戶端瀏覽器本次請求和響應的一個狀態。
            1. 狀態碼都是3位數字
            2. 分類:
              1. 1xx:伺服器就收客戶端訊息,但沒有接受完成,等待一段時間後,傳送1xx多狀態碼
              2. 2xx:成功。代表:200
              3. 3xx:重定向。代表:302(重定向),304(訪問快取)
              4. 4xx:客戶端錯誤。
                • 代表:
                  • 404(請求路徑沒有對應的資源)
                  • 405:請求方式沒有對應的doXxx方法
              5. 5xx:伺服器端錯誤。代表:500(伺服器內部出現異常)
        2. 響應頭:

          1. 格式:頭名稱: 值
          2. 常見的響應頭:
            1. Content-Type:伺服器告訴客戶端本次響應體資料格式以及編碼格式
            2. Content-disposition:伺服器告訴客戶端以什麼格式開啟響應體資料
              • 值:
                • in-line:預設值,在當前頁面內開啟
                • attachment;filename=xxx:以附件形式開啟響應體。檔案下載
        3. 響應空行

        4. 響應體:傳輸的資料

      • 響應字串格式
        HTTP/1.1 200 OK
        Content-Type: text/html;charset=UTF-8
        Content-Length: 101
        Date: Wed, 06 Jun 2018 07:08:42 GMT

        $Title$ hello , response

Response物件

  • 功能:設定響應訊息
    1. 設定響應行
    1. 格式:HTTP/1.1 200 ok
    2. 設定狀態碼:setStatus(int sc)
    2. 設定響應頭:setHeader(String name, String value)

      3. 設定響應體:
      	* 使用步驟:
      		1. 獲取輸出流
      			* 字元輸出流:PrintWriter getWriter()
    
      			* 位元組輸出流:ServletOutputStream getOutputStream()
    
      		2. 使用輸出流,將資料輸出到客戶端瀏覽器
    
    • 案例:
      1. 完成重定向

        • 重定向:資源跳轉的方式

        • 程式碼實現:
          [ //1. 設定狀態碼為302
          response.setStatus(302);
          //2.設定響應頭location
          response.setHeader(“location”,"/day15/responseDemo2"); ]

          ***//簡單的重定向方法
          response.sendRedirect("/day15/responseDemo2");

        • 重定向的特點:redirect

          1. 位址列發生變化
          2. 重定向可以訪問其他站點(伺服器)的資源
          3. 重定向是兩次請求。不能使用request物件來共享資料
        • 轉發的特點:forward

          1. 轉發位址列路徑不變
          2. 轉發只能訪問當前伺服器下的資源
          3. 轉發是一次請求,可以使用request物件來共享資料
        • forward 和 redirect 區別

        • 路徑寫法:

          1. 路徑分類
            1. 相對路徑:通過相對路徑不可以確定唯一資源
              • 如:./index.html

              • 不以/開頭,以.開頭路徑

              • 規則:找到當前資源和目標資源之間的相對位置關係

                • ./:當前目錄
                • …/:後退一級目錄
            2. 絕對路徑:通過絕對路徑可以確定唯一資源
              • 如:http://localhost/day15/responseDemo2 /day15/responseDemo2

              • 以/開頭的路徑

              • 規則:判斷定義的路徑是給誰用的?判斷請求將來從哪兒發出

                • 給客戶端瀏覽器使用:需要加虛擬目錄(專案的訪問路徑)

                  • 建議虛擬目錄動態獲取:request.getContextPath()

                  • , 重定向…

                • 給伺服器使用:不需要加虛擬目錄

                  • 轉發路徑
      2. 伺服器輸出字元資料到瀏覽器

        • 步驟:

          1. 獲取字元輸出流
          2. 輸出資料
        • 注意:

          • 亂碼問題:

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

            //簡單的形式,設定編碼,是在獲取流之前設定
            response.setContentType(“text/html;charset=utf-8”);
            PrintWriter pw = response.getWriter();
            pw.write(“hello你好”)

      3. 伺服器輸出位元組資料到瀏覽器

        • 步驟:
          1. 獲取位元組輸出流
          2. 輸出資料
            大多用位元組流輸出圖片
      4. 驗證碼

        1. 本質:圖片
        2. 目的:防止惡意表單註冊

    生成驗證碼圖片

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物件:

  1. 概念:代表整個web應用,可以和程式的容器(伺服器)來通訊
    1. 獲取:
      1. 通過request物件獲取
        request.getServletContext();
      2. 通過HttpServlet獲取
        this.getServletContext();
    2. 功能:
      1. 獲取MIME型別:
        • MIME型別:在網際網路通訊過程中定義的一種檔案資料型別

          • 格式: 大型別/小型別 text/html image/jpeg
        • 獲取:String getMimeType(String file)

@WebServlet("/servletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*

            ServletContext功能:
               1. 獲取MIME型別:
                * MIME型別:在網際網路通訊過程中定義的一種檔案資料型別
                    * 格式: 大型別/小型別   text/html		image/jpeg

                * 獲取:String getMimeType(String file)
                2. 域物件:共享資料
                3. 獲取檔案的真實(伺服器)路徑
         */
        
        //2. 通過HttpServlet獲取
        ServletContext context = this.getServletContext();

        //3. 定義檔名稱
        String filename = "a.jpg";//image/jpeg


        //4.獲取MIME型別
        String mimeType = context.getMimeType(filename);
        System.out.println(mimeType);


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
  1. 域物件:共享資料
    1. setAttribute(String name,Object value)
    2. getAttribute(String name)
    3. removeAttribute(String name)

ServletContext物件範圍:所有使用者所有請求的資料

  1. 獲取檔案的真實(伺服器)路徑
    1. 方法:String getRealPath(String path)
    String b = context.getRealPath("/b.txt");//web目錄下資源訪問
    System.out.println(b);
    String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪問
    System.out.println©;
    String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問
    System.out.println(a);
@WebServlet("/servletContextDemo5")
public class ServletContextDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*

            ServletContext功能:
               1. 獲取MIME型別:

                2. 域物件:共享資料
                3. 獲取檔案的真實(伺服器)路徑
         */
        
        // 通過HttpServlet獲取
        ServletContext context = this.getServletContext();


        // 獲取檔案的伺服器路徑
        String b = context.getRealPath("/b.txt");//web目錄下資源訪問
        System.out.println(b);
       // File file = new File(realPath);

        String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪問
        System.out.println(c);

        String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問
        System.out.println(a);


    }

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

案例: * 檔案下載需求:
1. 頁面顯示超連結
2. 點選超連結後彈出下載提示框
3. 完成圖片檔案下載

分析:
1. 超連結指向的資源如果能夠被瀏覽器解析,則在瀏覽器中展示,如果不能解析,則彈出下載提示框。不滿足需求
2. 任何資源都必須彈出下載提示框
3. 使用響應頭設定資源的開啟方式:
* content-disposition:attachment;filename=xxx

步驟:
1. 定義頁面,編輯超連結href屬性,指向Servlet,傳遞資源名稱filename
2. 定義Servlet
1. 獲取檔名稱
2. 使用位元組輸入流載入檔案進記憶體
3. 指定response的響應頭: content-disposition:attachment;filename=xxx
4. 將資料寫出到response輸出流

問題:
* 中文檔案問題
* 解決思路:
1. 獲取客戶端使用的瀏覽器版本資訊
2. 根據不同的版本資訊,設定filename的編碼方式不同

相關文章