day09_request&response學習筆記

============================================================

一、HttpServletResponse接口

    學好HttpServletResponseHttpServletRequest的關鍵是:理解HTTP協議。

    Web服務器收到客戶端的http請求,會針對每一次請求,分別創建一個用於代表請求的request對象、和代表響應的response對象。

    (注意:request和response分別表示的是對象名,實際上不是對象)

    request和response對象既然代表請求和響應,

    那我們要獲取客戶端提交過來的數據,只需要找request對象就行了。

    要向容器(服務器)輸出數據,只需要找response對象就行了。

    因爲每一的請求都會調用一次service(request, response)方法。

    方法的形參request和response是由服務器創建的,在service執行之前就已經創建好了,分別是兩個對象(是不需要new的,服務器幫你幹了)。

  1、響應消息行  HTTP/1.1  200 OK

        HTTP/1.1 200 OK

        協議/版本 響應狀態碼 對響應碼的描述(一切正常)

    HttpServletResponse接口的方法:

        void setStatus(int sc) 設置響應狀態碼

        response.setStatus(302);

        response.setHeader("location", "url");

        // 上面兩句代碼等價於下面一句

        response.sendRedirect("location");

           Location:http://www.it315.org/index.jsp   指示新的資源的位置通常和302/307一起使用,完成請求重定向

      請求轉發和請求重定向圖解:

  2、響應消息頭

    HttpServletResponse接口的方法:

      void sendRedirect(String location) 請求重定向

      void setHeader(String name, String value) 設置響應消息頭信息

      // 設置客戶端(瀏覽器)使用什麼編碼(通過響應消息頭設置)

      response.setHeader("content-type", "text/html; charset=UTF-8");

      // 告知客戶端不緩存

      response.setHeader("pragma", "no-cache");

      response.setHeader("cache-control", "no-cache");

      response.setDateHeader("expires", 0);

      Referesh刷新

  3、響應正文(主體)

    ServletResponse接口的方法:

      PrintWriter getWriter() 獲取字符輸出流

      ServletOutputStream getOutputStream() 獲取字節輸出流

      void setCharacterEncoding(String charset) 設置服務器使用什麼編碼

      String setContentType(String type) 設置將發送到客戶端的響應的內容類型(同時設置客戶端和服務端要使用的編碼)

例如:response.setContentType("text/html; charset=UTF-8");

      URLEncoder是HTML格式編碼的實用工具類,該類包含了將 String 轉換爲 application/x-www-form-urlencoded MIME 格式的靜態方法。

案例1:向客戶端輸出中文數據:用PrintWriter(字符流)發送數據

    案例2:向客戶端輸出中文數據:用OutputStream(字節流)發送數據

    案例3:客戶端下載文件

案例4:自己編寫代碼實現客戶端網頁顯示驗證碼

案例5:通過驗證碼工具類實現客戶端網頁顯示驗證碼

    案例6:實現定時刷新

  4、response的幾處細節

      1. getOutputStream和getWriter方法分別用於得到輸出二進制數據、輸出文本數據的ServletOuputStream、Printwriter對象。

      2. getOutputStream和getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再調用另一方法。否則會拋異常。

      3. Servlet程序向ServletOutputStream或PrintWriter對象中寫入的數據將被Servlet引擎從response裏面獲取,

         Servlet引擎將這些數據當作響應消息的正文,然後再與響應狀態行和各響應頭組合後輸出到客戶端。

      4. Serlvet的service方法結束後,Servlet引擎將檢查getOutputStream或getWriter方法返回的輸出流對象是否已經調用過close方法,如果沒有,Servlet引擎將調用close方法關閉該輸出流對象。

         (注:這裏的Servlet引擎就是Tomcat服務器)

============================================================

二、HttpServletRequest

  1、請求消息行 

      Get http://localhost:8080/day09_01_HttpServletRequest/servlet/req1?username=zs&pwd=123 HTTP/1.1

    HttpServletRequest接口的方法:

      String getMethod() 獲取請求行的請求方式

      String getRequestURL() 返回客戶端發出請求時的完整URL

      String getRequestURI() 返回請求消息行中的資源名部分(8080之後所有的)

      String getContextPath() 獲取當前應用的虛擬目錄 例如:/day09_01_HttpServletRequest

      String getQueryString() 返回請求消息行中的參數部分

  2、請求消息頭

    HttpServletRequest接口的方法:

      String getHeader(String name) 根據頭名稱得到頭信息值

      Enumeration getHeaderNames() 獲取所有請求消息頭的name

      Enumeration getHeaders(String name) 獲取相同請求消息頭名稱的信息值

  1 package com.itheima.servlet;
  2 
  3 import java.beans.IntrospectionException;
  4 import java.beans.PropertyDescriptor;
  5 import java.io.IOException;
  6 import java.io.UnsupportedEncodingException;
  7 import java.lang.reflect.InvocationTargetException;
  8 import java.lang.reflect.Method;
  9 import java.util.Enumeration;
 10 import java.util.Map;
 11 
 12 import javax.servlet.ServletException;
 13 import javax.servlet.http.HttpServlet;
 14 import javax.servlet.http.HttpServletRequest;
 15 import javax.servlet.http.HttpServletResponse;
 16 
 17 import org.apache.commons.beanutils.BeanUtils;
 18 
 19 import com.itheima.entity.User;
 20 
 21 public class ServletDemo3 extends HttpServlet {
 22 
 23     public void doGet(HttpServletRequest request, HttpServletResponse response)
 24             throws ServletException, IOException {
 25         // 告訴服務器要使用什麼碼錶,注:客戶端瀏覽器使用的是什麼碼錶,傳過來給服務器的就該使用什麼碼錶
 26         request.setCharacterEncoding("UTF-8"); // 注:只能處理post請求方式
 27 
 28         test1(request);
 29         test2(request);
 30         test3(request);
 31         test4(request);
 32     }
 33 
 34     private void test4(HttpServletRequest request) {
 35         try {
 36             User u = new User();
 37             System.out.println("封裝數據前:" + u);
 38 
 39             BeanUtils.populate(u, request.getParameterMap());
 40 
 41             System.out.println("封裝數據後:" + u);
 42         } catch (Exception e) {
 43             e.printStackTrace();
 44         }
 45     }
 46 
 47     private void test3(HttpServletRequest request) {
 48         try {
 49             User u = new User();
 50             System.out.println("封裝數據前:" + u);
 51             // 獲取表單數據
 52             Map<String, String[]> map = request.getParameterMap();
 53 
 54             for (Map.Entry<String, String[]> m : map.entrySet()) {
 55                 String name = m.getKey();
 56                 String[] value = m.getValue();
 57 
 58                 // 反射
 59                 // 創建一個屬性描述器對象
 60                 PropertyDescriptor pd = new PropertyDescriptor(name, User.class);
 61                 // 得到setter屬性對象
 62                 Method setter = pd.getWriteMethod();
 63 
 64                 if (value.length == 1) {
 65                     setter.invoke(u, value[0]); // 給只有一個值的變量賦值
 66                 } else {
 67                     setter.invoke(u, (Object) value); // 給複選框賦值
 68                 }
 69             }
 70 
 71             System.out.println("封裝數據後:" + u);
 72             
 73         } catch (Exception e) {
 74             e.printStackTrace();
 75         }
 76     }
 77 
 78     private void test2(HttpServletRequest request) {
 79         // 獲取表單提交的所有的name的名稱
 80         Enumeration names = request.getParameterNames();
 81         while (names.hasMoreElements()) {
 82             String name = (String) names.nextElement(); // 得到每一個name名稱
 83             String[] values = request.getParameterValues(name); // 根據name名稱,得到value值
 84             for (int i = 0; values != null && i < values.length; i++) {
 85                 System.out.println(name + "\t" + values[i]);
 86             }
 87         }
 88     }
 89 
 90     private void test1(HttpServletRequest request) throws UnsupportedEncodingException {
 91         // 獲取表單數據
 92         // 根據表單中name屬性的名,獲取value屬性的值方法
 93         String username = request.getParameter("username");
 94         String pwd = request.getParameter("pwd");
 95         String sex = request.getParameter("sex");
 96         String[] hobbys = request.getParameterValues("hobby");
 97         String city = request.getParameter("city");
 98 
 99         // 解決get方式編碼
100         username = new String(username.getBytes("iso-8859-1"), "UTF-8");
101         
102         System.out.println(username);
103         System.out.println(pwd);
104         System.out.println(sex);
105 
106         for (int i = 0; hobbys != null && i < hobbys.length; i++) {
107             System.out.print(hobbys[i] + "\t");
108         }
109         System.out.println();
110 
111         System.out.println(city);
112     }
113 
114     public void doPost(HttpServletRequest request, HttpServletResponse response)
115             throws ServletException, IOException {
116         doGet(request, response);
117     }
118 
119 }

  3、請求正文(重要)

    與獲取表單數據相關的方法:

      <input type="text" name="username" />

     ServletRequest接口的方法:

      String getParameter(String name) 根據表單中name屬性的名,獲取value屬性的值

      String[] getParameterValues(String name) 專爲複選框獲取值提供的方法

      Enumeration getParameterNames() 獲取表單提交的所有的name名

      Map getParameterMap() 獲取表單提交的所有value值  (做框架時用,非常實用)

      ServletInputStream getInputStream 以字節流的方式得到所有表單數據

    與操作非表單數據相關的方法:(request也是一個域對象,也維護了一個Map集合,只是作用的範圍較小,在當前請求範圍內有效)

     ServletRequest接口的方法:

      void setAttribute(String name, Object value)

      Object getAttribute(String name)

      void removeAttribute(String name)

與請求轉發相關的方法:

      ServletRequest接口的方法:

      // 得到請求轉發或請求包含的協助對象

      RequestDispatcher getRequestDispatcher(String path)

      RequestDispatcher接口的方法:

        void forward(ServletRequest request, ServletResponse response) // 轉發的方法

        void include(ServletRequest request, ServletResponse response) // 請求包含

    與請求編碼相關的方法:

      ServletRequest接口的方法:

      // 解決post提交方式的編碼

      request.setCharacterEncoding("UTF-8"); // 告訴服務器要使用什麼碼錶,注:只能處理post請求方式

      // 解決get提交方式的編碼(需要一個一個變量的轉換,麻煩,用的不多,一般用在地址欄上明文寫的鏈接上,因爲明文是get方式提交)

      String name = new String(name.getBytes("iso-8859-1"), "UTF-8");

      注:一般而言,默認是get提交方式,所以我們在寫表單的html代碼時,要立即把表單的屬性method="post" 最好。

request與response對象解決亂碼的應用:

============================================================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章