01_響應對象的概述&向客戶端發送數據
WEB服務器會針對每一個客戶端發出的HTTP請求,分別的創建一個請求對象和一個響應對象如果需要獲取客戶端提交的數據,需要使用請求對象
如果需要向客戶端發送一些數據,需要使用響應對象
響應 : 響應行 響應頭 響應正文
1XX:瀏覽器發送的請求信息不完善,需要瀏覽器進一步補充資料
2XX:響應正常完成
3XX:本次請求已經完成,但是需要瀏覽器進行進一步操作 302
4XX:請求的資源錯誤
5XX:服務器端錯誤
注意:
這兩個流互相排斥,在一個Servlet中只能使用其中的一個,如果有字符輸出流則不能有字節輸出流,否則會出現
02_字節流向客戶端發送中文的亂碼處理
編碼:二進制 A 65 a 97 漢字
ASCII 美國標準信息碼(128字符)
ISO-8859-1 -16 一共有15編碼 13
//GB2312 2個字節表示一個字符 6700+
GBK 2個字節表示一個字符 18000+ 國家強制標準
Unicode 萬國碼 2個字節表示一個字符
UTF-8 用1-6個字節來表示一個字符
ANSI 本地平臺默認
中文版window GBK
英文版的window UTF-8
原因:
亂碼的出現是因爲前後編碼不一致,發送數據的編碼,接收數據的編碼
服務器發送數據:ISO-8859-1
瀏覽器接收數據:GBK
解決方法一:
將服務器發送數據格式改爲GBK
OutputStream os = response.getOutputStream();
os.write("黑馬程序員".getBytes());//默認GBK
解決方法二
//設置響應頭,告訴瀏覽器你應該使用什麼編碼
response.setHeader("Content-type", "text/html;charset=UTF-8");
os.write("黑馬程序員".getBytes("UTF-8"))
03_字符流向客戶端發送中文的亂碼處理
原因服務器發送數據:ISO-8859-1 -> GBK
瀏覽器接收數據:GBK
解決方法一:
response.setCharacterEncoding("GBK");//設置編碼的格式,也就是設置服務器發送數據的格式
如果服務器發送的是UTF-8
response.setCharacterEncoding("UTF-8");//服務器
response.setContentType("text/html;charset=UTF-8");//告訴瀏覽器採用什麼方式進行解碼
推薦方案
response.setContentType("text/html;charset=UTF-8");//告訴瀏覽器採用什麼方式進行解碼
04_響應頭Refresh
定時自動刷新response.setHeader("Refresh", "3");
定時自動跳轉
response.setHeader("Refresh", "3;URL=http://www.itcast.cn"); //跳轉外部資源
response.setHeader("Refresh", "3;URL=/myResponse/ResponseDemo");//跳轉內部資源
轉發和跳轉的區別
轉發:共享請求和響應對象,跳轉:不共享
轉發:只能是內部地址,跳轉:內部地址和外部地址都可以
轉發:地址欄不會發生變化,跳轉:地址欄會發生變化
05_請求重定向
概念:一個WEB資源接收到客戶端的請求之後,通知這個客戶端去訪問(請求)另外的一個WEB資源重定向和轉發的區別
請求次數
重定向發出兩次請求
轉發只發出一次請求,共享請求對象和響應對象
訪問的路徑
重定向可以訪問內部的路徑,也可以訪問外部的路徑
轉發只能訪問內部的路徑
地址欄
重定向的地址欄發生變化
轉發地址欄不會變化
原理:設置location響應頭,同時還需要設置一個響應碼(狀態碼),302/307
response.setHeader("Location", "http://www.itcast.cn");
response.setStatus(307); //立即重定向
06_文件下載案例
步驟//設置響應頭
response.setHeader("Content-disposition", "attachment;filename=pic01.jpg");
//獲取字節輸出流對象
OutputStream os = response.getOutputStream();
//創建字節輸入流對象
String path = getServletContext().getRealPath("/WEB-INF/pic01.jpg");
FileInputStream fis = new FileInputStream(path);
//循環讀取並向客戶端發送數據
int len = 0;
byte[] bys = new byte[1024];
while((len = fis.read(bys)) != -1) {
//向客戶端發送數據
os.write(bys,0,len);
}
//釋放資源
fis.close();
07_文件下載的細節
注意:響應頭裏不能有中文,中文被認爲是不安全的字符
更改如下:
String s = URLEncoder.encode("傳智專修學院.jpg", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + s);
08_請求對象的概述&獲取請求行
HttpServletRequest請求對象封裝了HTTP協議的請求行,請求頭,請求體,我們可以通過請求對象的方法來獲取這些信息
獲取請求行
StringBuffer getRequestURL() //完整的URL
String getRequestURI() //請求行中的資源路徑
String getMethod() //請求方式
String getContextPath() //當前項目的路徑
String getQueryString() //請求行中資源路徑後面的參數
注意:
getRequestURL()返回的是一個可變字符串,不能直接使用String來接收
getQueryString()獲取的是資源路徑後面的參數,請求體裏的數據無法獲取
09_獲取請求頭
String getHeader(String name) //通過name來獲取請求頭valueEnumeration getHeaderNames() //獲取所有的請求頭name
Enumeration迭代遍歷
Enumeration<String> e = request.getHeaderNames();
while(e.hasMoreElements()) {
String name = e.nextElement();
System.out.println(name);
}
10_獲取表單提交的數據
String getParameter(String name) :根據表單項的name來獲取表單項的value注意:
有表單項提交過來,但是沒有值, 打印的是空字符串
表單項根本沒有提交過來,打印的就是null,就不能調用字符串的方法,否則會報空指針異常
11_獲取表單提交的數據2
String[] getParameterValues(String name) 根據表單項的name獲取表單項value的數組應用場景: name是重複的,比如密碼確認密碼 複選框
12_獲取表單提交的數據3
Map getParameterMap(): 獲取表單提交來的所有數據,並封裝成一個map返回,一些框架(工具類)會使用這個方法Enumeration getParameterNames() 獲取提交過來表單項所有的name
返回值使用泛型時應該是Map<String,String[]>形式,
因爲有時像checkbox這樣的組件會有一個name對應對個value的時候,
所以該Map中鍵值對是<String-->String[]>的實現。
注意:
註冊按鈕提交過來沒有意義,所以註冊按鈕千萬不要寫個name屬性
14_獲取表單提交的數據亂碼的處理
原因:編碼前後不一致
表單提交數據用的是UTF-8
請求對象接收數據轉換成字符串 用的是默認的ISO-8859-1
對於post請求
request.setCharacterEncoding("UTF-8");//只能處理請求體,這裏設置請求對象創建字符串所使用的編碼是UTF-
對於get請求
瀏覽器
按照表單頁面的編碼(UTF-8)進行轉碼,轉成字節數組,拼接在請求資源的後面
接下來把字節數組做一個轉義(url編碼)在發送
服務器
服務器首先拿到這個數據做一個url解碼,(正確的)
然後把解碼之後的數據按照ISO-8859-1拼成字符串(錯誤)
做法:
//把字符串打回原形
byte[] bys = request.getParameter("username").getBytes("ISO-8859-1");
//把字節數組按照正確的編碼轉換字符串
String username = new String(bys,"UTF-8");
15_轉發和包含
用ServletContext實現轉發和包含,路徑必須以正斜槓開頭RequestDispatcher rd = getServletContext().getRequestDispatcher("/register.html");
rd.forward(request, response);
rd.include(request, response);
用request對象實現轉發和包含,路徑可以不用正斜槓開頭
RequestDispatcher rd = request.getRequestDispatcher("register.html");
rd.forward(request, response);
rd.include(request, response);
16_使用請求對象實現數據共享
ServletContext 上下文對象 範圍是當前的web應用時間範圍 tomcat 一加載項目 tomcat關閉
空間範圍 整個web應用
request 請求對象 範圍是當前的請求 需要同一個請求才能實現數據的共享
時間範圍 一個請求開始,請求結束
空間範圍 當前這個請求裏面
//設置數據
request.setAttribute("username", "zhangsan");
//獲取數據
Object obj = request.getAttribute("username");
System.out.println(obj);
//刪除數據
request.removeAttribute("username");
//轉發
RequestDispatcher rd = request.getRequestDispatcher("/RequestDemo9");
rd.forward(request, response);
訪問網站訪問量