============================================================
一、HttpServletResponse接口
學好HttpServletResponse與HttpServletRequest的關鍵是:理解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對象解決亂碼的應用:
============================================================