JavaWeb(三) ----Servlet處理HTTP響應,請求
Servlet處理HTTP響應
設定響應狀態行
狀態行:HTTP協議,狀態碼,狀態描述。
HTTP狀態碼:
1. 100-199 :表示資訊性程式碼,標示客戶端應該採取其他動作,請求正在進行。
2. 200-299 :表示客戶請求成功。
3. 300-399 :表示用於已經移走的資原始檔,指示新的地址
4. 400-499 :表示由客戶端引發的錯誤。
5. 500-599 :表示由伺服器端引發的錯誤。
設定狀態碼
使用HttpServlet的setStatus();
使用HttpServlet的sendError(狀態碼,狀態描述);
設定狀態碼重定向,請求資源不存在,再次請求到另外的資源:
response.setStatus(302);
response.setHeader("Location","index.jsp");
也可以用:
response.sendRedirect("http://127.0.0.1:8080//lovobook/bar.html")
把請求重定向到一個完全不同的url上(選擇別的伺服器端程式來處理請求)
重定向:
1. 重定向的狀態碼是302,表示資源被移走,重新請求新的資源。
2. 重定向是客戶端發起的2次請求。
3. 呼叫sendRedirect方法可以不用設定狀態碼,會自動把狀態碼設定為302
設定響應頭
HttpServletResponse 物件用於操作響應的響應頭。
1.設定響應內容的型別MIME型別
什麼是MIME型別:
告訴瀏覽器伺服器傳送回去的資料型別是什麼,客戶端啟動的相應的應用程式來處理響應內容。
response.setContentType("text/html");
response.setContentType("image/gif");
......
2.設定響應頭
通過響應頭設定MIME型別:
/*類似於 <meta charset = utf-8>*/ esponse.setHeader("Content-Type","text/html;charset=utf-8");
自動重新整理功能:
/後面數字的單位是秒,不是毫秒了/
response.setHeader("refresh","1")
response.setHeader("refresh","1;index.jsp");在一秒後跳轉
控制資料是否快取:
response.setHeader("Pragma","NO-cache");
response.setHeader("Cache-Control","No-cache");
設定過期時間(快取到什麼時候):
response.setDateHeader("Expries",System.currentTimeMillis());
3.設定響應訊息體
HttpServletResponse物件負責將資訊返回給客戶端
HttpServletResponse物件只產生一個空的http響應。
傳回自定義的內容需要getWriter()或者
getOutputStream()方法。
-傳送普通文字
-傳送二進位制內容
傳送普通文字:
//tomcat預設響應客戶端解析的時候編碼集是ISO-8859-1
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print();
out.write();
//write(),print()方法區別:
//共同點:兩者都不會重新整理頁面,只在原來的頁面上寫資料。兩個方法都是重寫了Writer類裡面的write方法。
//不同點:print方法可以將各種不同的資料轉換為字串輸出,write方法只能操作字元,或者字元陣列,字串,只能操作和字串相關的
//輸出中文瀏覽器
//設定傳輸過程中編碼格式是utf-8,一般寫在最上面
respons.setCharacterEncoding("utf-8");
傳送二進位制:
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//獲取到輸出流物件
OutputStream out = response.getOutputStream();
//將字串轉換成位元組陣列
byte[] ca = str.getBytes();
out.write(ca);
檔案下載:
protecter void doGet(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
resp.setCharacterEncoding("utf-8");
resp.setContentType("image/jpeg");
//獲取到檔案要下載的路徑,通過上下文物件獲取到檔案的物理路徑
String path = this.getServletContext().getRealPath("/image/1.jpg");
//設定響應頭,控制瀏覽器開啟下載框
resp.setHeader("Content-disposition","attachment;fileName=1.jpg")
{
如果是中文的路徑:操作圖片的中文名字也要轉換為位元組陣列,還要保持編碼級和伺服器一致。
String path = this.getServletContext().getRealPath("/image/高圓圓.jpg");
resp.setHeader("Content-disposition","attachment;fileName="+new String(path.getBytes("utf-8"),"ISO8859-1"))
}
//獲取到圖片的二進位制流
InputStream in = new FileInputStream(path);
//建立一個二進位制流
OutputStream out = resp.getOutputStream();
//建立一個緩衝區
int len = 0 ;
byte[] by = new byte[1024]
while((len = in.read(by))!= -1){
out.write(by,0,len);
}
}
通過字元流操作二進位制檔案,有可能出現內容丟失
Servlet處理HTTP請求
HttpServletRequest 物件主要使用者獲取客戶端傳送過來的請求頭,狀態行,空行,訊息體
GET/POST 提交方法
GET方法提交
- 位址列直接輸入伺服器資源
- 通過js直接訪問
- 超連結訪問預設也是GET提交
用於獲取到伺服器的資源。
POST提交
主要是用於傳輸資料。客戶端向伺服器傳送資料,一般用post。可以傳送文字資料,二進位制資料。
特徵 | GET方法 | Post方法 |
提交資料型別 | 文字 | 文字、二進位制文字 |
提交資料長度 | 不超過255字元 | 沒有限制 |
提交資料可見性 | 作為URl地址的一部分顯示 | 作為請求的訊息體,不可見 |
提交資料快取 | 快取在瀏覽器URL歷史狀態中 | 不會被瀏覽器快取 |
何時使用GET/POST方法:
- 請求一個靜態頁面或者圖形檔案時用GET方法
- 傳送大資料的時候,使用POST方法
- 上傳檔案時,使用POST方法
- 傳送使用者名稱,密碼或其他保密資訊的時候用POST方法
方法操作
獲取請求行
http 傳送的請求行的內容全部封裝到了request物件,可以直接呼叫方法獲取到請求行的內容
1.獲取到客戶端請求的方法
String method = request.getMethod();
2.獲取到請求的URL地址
String URL = request.getRequestURL().toString();
String URI = request.getRequestURI()
URL:統一資源定位符(實實在在的全路徑)
URI:統一資源標誌符
3.獲取到請求過程中附帶的引數
String qu = request.getQueryString();
4.獲取到客戶端的IP
String ipstr = request.getRemoteAddr();
5.獲取到伺服器的埠
int port = request.getLocationPort();
獲取請求頭
1.獲取到請求頭
String agent = request.getHeader("User-Agent");
傳入一個請求頭名字
2.獲取到所有的請求頭
Enumeration num = request.getHeaderNames();
3.獲取到日期型別的請求頭
Date date = request,getDateHeader(arg0);
獲取訊息體
request封裝了客戶端傳過來的資料
在POST提交的方法內部:
要在開始設定編碼集
request.setCharacterEncoding("utf-8");
1.獲取到訊息體
String username = request.getParameter("username");
2.獲取到客戶端傳入的多個數據(eg:複選框)
String[] s = request.getParameterValues("like")
注意:提交中文一般採用POST,GET提交預設亂碼,需要自己處理編碼集。
String name = reques.getParameter(“uesename”);
String newName = new String(name.getBytes(“ISO8859-1”),”utf-8”);
請求派發(內部派發)
- 每個客戶的請求可以傳遞給很多Servlet以及web應用程式中的其他資源
- 整個過程完全是在服務端完成的
- 不需要任何客戶端瀏覽器的行為
- 不需要在客戶端瀏覽器和伺服器端之間傳遞特殊資訊
通過javax.servlet.RequestDispatcher物件實現
RequestDispatcher rd = request.getRequestDispatcher(“html/succes.html”);
/指定跳轉資源,如果是servlet就直接寫名字就可以了/
rd.forward(request,response);
/客戶端還是原來的地址,不會改變為新的地址/
rd.include(request,response);
/是把資源的控制權移交給下一個資源,當下一個資源操作完畢後,最後將控制權再回收到本資源中,最後響應客戶端的也是本資源/
當前請求派發後,這個資源就將控制權移交給下一個資源了,就沒有響應的能力了。
請求派發預設呼叫dopost()
請求派發和重定向的區別:
1. 請求派發的狀態碼是307,重定向是302.
2. 請求派發是在伺服器端完成的,不影響客戶端,位址列不會變化。重定向是客戶端來完成,位址列會變化。
3. 請求派發只能在本伺服器完成,重定向是可以訪問其他伺服器的資源。
注意:如果是客戶端提交過來的內容 /JavaWeb04/xxxxx 前面的第一個/只能到達webapps ,所以要加上工程名字。