web基礎day9--request-response請求與響應

  1. request
    代表HTTP請求。
    a. HTTP請求由四部分組成:
    請求行 get 請求資源名稱 HTTP協議版本
    多個請求頭
    一個空行
    請求實體內容 請求參數
    b. 請求的繼承結構
    ServletRequest
    |
    |----HttpServletRequest 在原有接口之上添加了HTTP協議相關的API,更善於HTTP協議相關開發。
    1. 請求的功能
      a. 獲取請求資源
      getRequestURL方法 – 返回客戶端發出請求完整URL
      getRequestURI方法 – 返回請求行中的資源名部分
      getQueryString方法 – 返回請求行中的參數部分
      getRemoteAddr方法 – 返回發出請求的客戶機的IP地址
      getMethod – 得到客戶機請求方式
      !!getContextPath – 獲得當前web應用虛擬目錄名稱 – 在寫路徑時不要將web應用的虛擬路徑的名稱寫死, 應該在需要寫web應用的名稱的地方通過getContextPath方法動態獲取

      b. 獲取請求頭
      getHeader(name)方法 — String
      getHeaders(String name)方法 — Enumeration
      getHeaderNames方法 — Enumeration
      getIntHeader(name)方法 — int
      getDateHeader(name)方法 — long(日期對應毫秒)

      c. 獲取請求實體內容
      getParameter(String name) — String 通過name獲得值
      getParameterValues(String name) — String[ ] 通過name獲得多值 checkbox
      getParameterMap() — Map<String,String[ ]> key :name value: 多值 將查詢的參數保存在一個Map中
      getParameterNames() — Enumeration 獲得所有name
      i. 在獲取請求參數時,如果獲取中文數據,則會出現亂碼。
      ii. 亂碼產生的原因:
      編碼和解碼字符集不統一。
      iii. 瀏覽器負責發送數據,在發送數據時會對數據編碼,發送數據時所使用的字符集是頁面加載時的字符集,爲utf-8。
      iv. 接收數據的是服務器,服務器在接收數據時會採用默認字符集iso8859-1解碼數據。
      v. 發送與接收字符集不同意,所以出現了亂碼。由於iso8859-1中沒有中文,所以應該將兩者統一爲utf-8。修改服務器的字符集。
      vi. 如果是post提交,可以進行如下修改:
      在所有獲取請求參數的代碼之前,書寫:
      request.setCharacterEncoding(“utf-8”);
      這句話僅能處理請求實體內容中的請求參數亂碼,所以只對post請求有效。get請求無效。
      vii. 如果是get請求,則需要在獲取參數之後,先使用iso8859-1編碼,在使用utf-8解碼。
      1) 代碼如下:
      new String(username.getBytes(“iso8859-1”),“utf-8”);
      這種形式,既可以解決get提交的亂碼,也可以解決post提交的亂碼。

    2. request功能–請求轉發
      請求轉發是一種資源跳轉方式,發生的服務器內部。

      a. 代碼實現:

       import java.io.IOException;
       
       import javax.servlet.RequestDispatcher;
       import javax.servlet.ServletException;
       import javax.servlet.http.HttpServlet;
       import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       
       public class RequestDemo4 extends HttpServlet {
       
               public void doGet(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       //創建一個調度器
                       RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo5");
                       //利用調度器實現請求轉發
                       rd.forward(request, response);
               }
       
               public void doPost(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       doGet(request, response);
       
               }
       
       }
      

      b. 請求轉發細節:
      i. 請求轉發之前如果向response緩衝區中寫入數據,這些數據在請求轉發是會被清空。
      ii. 如果沖刷緩衝區,會造成一次響應,導致請求轉發失敗.所以不能沖刷緩衝區.
      iii. 請求轉發可以多重轉發,但是不能在同一個servlet內多次請求轉發.
      iv. 在請求轉發前後的代碼也會正常執行.
      v. 多個請求轉發會組成一個請求鏈,請求鏈的執行順序是先執行所有請求轉發之前的代碼,在反向指向全部請求轉發之後的代碼.

    3. request功能–請求包含
      可以將兩個servlet結果合併爲一個結果輸出.

    4. request功能–作爲域對象使用
      a. 什麼是域對象?
      i. 如果一個對象身上有一個可以被看見的範圍,在這個範圍內利用對象身上的map,實現數據的共享,這個對象就可以叫做域對象。
      b. 在域對象身上可以設有域屬性,操作域屬性的api如下:
      設置域屬性:setAttribute(String name,Object obj);
      獲取域屬性:getAttribute(String name);
      刪除域屬性:removeAttribute(String name);
      獲取全部域屬性的名稱:getAttributeNames();
      注意:
      請求參數是Parameter,會隨着form表單發送到服務器,通過getparameter()及其相關api獲取.
      域屬性是request對象作爲域對象使用時,特有的屬性。通過setAttribute設置,getAttribute獲取。
      域屬性和請求參數是兩個不同的數據,API不能混用。
      c. 練習:在servlet中設置域屬性,在index.jsp頁面獲取域屬性。
      RequestDemo10.java

       import java.io.IOException;
       
       import javax.servlet.ServletException;
       import javax.servlet.http.HttpServlet;
       import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       //request作爲域對象使用
       public class RequestDemo10 extends HttpServlet {
       
               public void doGet(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       //在servlet中設置域屬性
                       request.setAttribute("name", "曹洋");
                       request.setAttribute("age",18);
                       request.setAttribute("gender", "女");
                       request.setAttribute("wife", "麗麗");
                       //爲了能夠讓當前servlet和index.jsp頁面共享一個範圍,需要實現請求轉發
                       request.getRequestDispatcher("/index.jsp").forward(request, response);
                       
               }
       
               public void doPost(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       doGet(request, response);
       
               }
       
       }
        index.jsp:
       	<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
       	<!DOCTYPE HTML>
       <html>
         <head>
           
         </head>
         
         <body>
          	<h3>在index.jsp頁面獲取域屬性</h3>
          	姓名:<%=request.getAttribute("name") %><br>
          	年齡:<%=request.getAttribute("age") %><br>
          	性別:<%=request.getAttribute("gender") %><br>
          	伴侶:<%=request.getAttribute("wife") %><br>
         </body>
       </html>
      

      d. 生命週期:
      當請求鏈開始的時候,request對象創建,
      當請求鏈結束的時候request對象銷燬。
      e. 作用範圍:
      整個請求鏈。
      f. 主要功能:

response概述

代表HTTP響應。
8. response繼承結構
ServletResponse
|
|—HttpServletResponse 在基礎的response接口之上添加了HTTP協議相關的內容,善於HTTP協議相關開發。
9. response組成
狀態行 HTTP協議版本 狀態碼 200 原因敘述OK
多個響應頭 location refresh Expires Cache-control pragma
一個空行
響應實體內容 響應數據 HTML json
302 +location 請求重定向
304 緩存
404 資源路徑不存在
500 服務器報錯
10. response操作
§ 設置狀態碼的方法
void setStatus(int sc)
void setStatus(int sc, String sm)
§ 設置響應頭的方法
void setHeader(String name, String value)
void setDateHeader(String name, long date)
void setIntHeader(String name, int value)
void addHeader(String name, String value)
void addDateHeader(String name, long date)
void addIntHeader(String name, int value)
§ 設置響應內容的方法
ServletOutputStream getOutputStream()
PrintWriter getWriter()

response

在response的響應實體內容中,可能會包含中文,這樣就可能需要進行亂碼處理。在面對response的字節流和字符流時,有不同的處理方法。
a. 字節流
response.getOutputStream()以字節流的形式發送數據,
i. 在將字符轉換爲byte類型數據時,如果採用默認的平臺碼GBK。則直接發送到瀏覽器不會產生亂碼。因爲瀏覽器也是GBK字符集。兩者統一。
ii. 在字符轉換爲byte類型數據時,使用utf-8進行轉換,那麼瀏覽器接收數據必須也是utf-8字符集。所以應該通知瀏覽器使用utf-8接收。通知瀏覽器的方式:
response.setHeader(“Content-Type”,“text/html;charset=utf-8”);
b. 字符流
response.getWriter()以字符流的形式發送數據。
i. 服務器在發送字符流數據的時候,底層仍然是以字節流的形式發送。發送是會採用當前服務器默認的字符集轉換字符爲字節,所以會使用iso8859-1來編碼數據。
ii. 瀏覽器接收數據是GBK,現在要求服務器發送數據和瀏覽器接收數據都是用utf-8。所以需要通知服務器使用utf-8發送數據,及通知瀏覽器使用utf-8接收數據
//通知服務器發送數據時的字符集
response.setCharacterEncoding(“utf-8”);
//通知瀏覽器接收數據時的字符集
response.setHeader(“Content-Type”, “text/html;charset=utf-8”);
iii. 總結:
1) 在通知瀏覽器使用某一字符集接收數據時,服務器會自動採用此字符集來發送數據。
2) 不論是字節流還是字符流,都通過通知瀏覽使用utf-8字符集這種形式,來解決亂碼問題。
response.setHeader(“Content-Type”, “text/html;charset=utf-8”);
<==>
response.setContentType(“text/html;charset=utf-8”);

注意:
1) 亂碼處理的語句需要放在所有的響應內容之前。
2) 字節流和字符流不能同時使用。
3) 不要關閉字節流和字符流,會導致服務器異常。瀏覽器會自動結束這些流。

請求重定向

是一種資源跳轉方式。可以在不同服務器之間進行跳轉。

a. 實現原理
設置狀態碼302
設置響應頭location
//實現原理:302+location
response.setStatus(302);
response.setHeader(“location”, “/day09-reqres/servlet/RequestDemo9”);
response.setHeader(“location”, “http://www.xxx.cn”);
response.sendRedirect(“http://www.csdn.net”);

定時刷新

在這裏插入圖片描述

  1. 請求轉發–request

    請求轉發的特點:
    一次請求 一次響應
    一個請求對象 一個響應對象
    服務器內部的資源跳轉方式(其實僅限於當前web應用內部)
    瀏覽器地址欄不發生改變

    1. 請求重定向–response

      請求重定向特點:
      兩次請求 兩次響應
      兩個請求對象 兩個響應對象
      服務器之間的資源跳轉方式
      瀏覽器地址欄會發生變化

    2. 定時刷新–response

      定時刷新的特點:
      兩次請求 兩次響應
      兩個請求對象 兩個響應對象
      服務器之間的資源跳轉方式
      瀏覽器地址欄會發生變化
      a. 定時刷新和請求重定向到區別:
      定時刷新會經過指定時間之後再跳轉。定時刷新是通過refresh響應頭實現。
      請求重定向會在執行時立刻發生跳轉。請求重定向是通過302狀態碼加上location響應頭實現。

    3. ~情景
      a. 要求在同一個服務器內部跳轉?
      請求轉發、請求重定向、定時刷新都能實現。
      b. 要求在不同不服務器之間跳轉?
      請求重定向、定時刷新都可以實現。
      c. 要求地址欄不發生變化?
      請求轉發
      d. 要求地址欄發生變化?
      請求重定向、定時刷新都可以實現。
      i. 要求經過指定時間之後再跳轉?
      定時刷新可以實現。
      ii. 立刻跳轉的情景
      搜索、查閱商品信息
      iii. 經過指定時間的情景
      轉賬,購物、註冊

在這裏插入圖片描述

  1. 控制瀏覽器不使用緩存
    Expires HTTP/1.0
    Cache-Control HTTP/1.1
    pragma HTTP/1.0
    Expires存儲一個毫秒值,這個毫秒值從1970-01-01的0點開始計算。
    Expires -1
    Cache-Control no-cache不使用緩存 ~~ no-store 不緩存
    pragma no-cache
    //控制瀏覽器不使用緩存
    //表示1970-01-01的0點基礎上再減去一毫秒。此事件無效,所以會加載最新資源。
    response.setDateHeader(“Expires”, -1);
    //不使用緩存
    response.setHeader(“Cache-control”, “no-cache”);
    //不使用緩存
    response.setHeader(“pragma”, “no-cache”);
    1. 控制瀏覽器使用緩存
      Expires HTTP/1.0
      Cache-Control HTTP/1.1
      pragma HTTP/1.0
      Expires 在先有時間之上,再加上一些時間,這些被加上的時間,就是緩存可以被使用的時間長度。 +1000606024
      //控制瀏覽器使用緩存
      response.setDateHeader(“Expires”, System.currentTimeMillis()+1000
      606024);//24小時
      response.setHeader(“Cache-control”, “max-age=5”);//5秒
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章