1. 程式人生 > >day_1_11 JavaWeb系列學習總結之response&request

day_1_11 JavaWeb系列學習總結之response&request

Response物件

就是伺服器用來向瀏覽器響應內容的

1. 獲取響應流

在servlet中可以用response物件獲取一個位元組流或者一個字元流
PrintWriter pw = response.getWriter(); // 字元流
OutputStream out = response.getOutputStream(); // 位元組流
注意: 在一個Servlet中, 只能使用一種流, 不然就會丟擲IllegalStateException異常

2. response設定響應頭

setHeader(String name, String value) 設定響應頭


示例:

// 設定響應編碼
response.setHeader("Content-type", "text/html;charset=utf-8");

// 使用Refresh響應頭來完成頁面的定時跳轉
response.getWriter().print("註冊成功, 3秒後跳轉到主頁!");
response.setHeader("Refresh", "3;URL=http://www.baidu.com");
3. 設定狀態碼
// 設定錯誤狀態碼
void sendError(int sc)
// 設定錯誤狀態碼, 並且給出錯誤提示資訊
void sendError(int sc, String msg)
// 設定狀態碼
void setStatus(int sc)

重定向
當用戶訪問某一個servlet的時候, 該servlet向客戶端響應一個302的狀態碼, 並且響應一個location響應頭, 頭值為一個地址, 客戶端會自動再次訪問該地址.
那麼在這個過程中, 客戶端傳送了兩次請求, 重定向的地址可以是本專案, 也可以是其它的專案, 所以重定向的路徑前面必須有專案名, 也可以使用相對路徑(但是不建議), 重定向改變了瀏覽器的位址列

    response.setStatus(302);
    response.setHeader("location", "http://www.baidu.com"
);

重定向的快捷方法:
response.sendRedirect("/day_1_11/index.jsp");

HTTP

Http協議: 客戶端跟伺服器進行資料傳輸的標準

請求和響應:
請求頭:
Referer: 該請求頭意思是 該請求來自於哪裡, 可以用來做統計和防盜鏈, 如果是直接從瀏覽器輸入的網址, 那麼是沒有該請求頭的
User-Agent: 用來獲取瀏覽器的資訊

響應頭:
Refresh: 定時跳轉
Location: 重定向的頭
Content-type: 設定字元編碼

響應狀態碼:

404: 訪問的資源路徑不存在
500: 一般是伺服器程式碼報錯, 拋異常
405: servlet中沒有重寫doGet或者doPost方法, 但是提交方式是doGet或者doPost
302: 重定向的狀態碼
200: 正常響應

304: 第一次訪問靜態資源的時候, 伺服器會向瀏覽器傳送一個響應頭Last-Modified:Thu, 11 Jan 2018 00:52:17 GMT表示最後修改該檔案的時間.
第二次訪問該靜態資源的時候, 瀏覽器會帶一個請求頭給伺服器If-Modified-Since:Thu, 11 Jan 2018 00:52:17 GMT
表示的是檔案最後修改的時間, 如果兩次時間一致的話, 那麼第二次訪問的時候, 伺服器知道該檔案在兩次訪問之間沒有被修改過, 伺服器就會發送一個304狀態碼告訴瀏覽器, 你不需要我來響應, 使用你自己的快取即可

錯誤狀態的解決方案

如果在訪問某些資源的時候, 出現了404, 500, 405等等錯誤狀態碼, 那麼我們可以給使用者一定的友好提示, 可以設定一個錯誤的頁面, 遇到錯誤就跳轉到錯誤頁面.

可以通過狀態碼, 也可以通過異常的型別, 但它們不能同時出現在一個裡

<error-page>
        <error-code>404</error-code>
        <location>/error1.html</location>
</error-page>

<error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error2.html</location>
</error-page>

Request

封裝了瀏覽器傳送過來的所有請求資訊

1. 獲取請求引數

request.getParameter("");

2. 獲取請求路徑資訊:
// 獲取上下文路徑, 即專案名
String getContextPath()
// 獲取請求方式
String getMethod()

// 獲取請求引數
String getQueryString()

String getRequestURI()
String getRequestURL()

// 獲取servlet路徑
String getServletPath()
// 獲取IP地址
String getRemoteAddr()
// 獲取主機名
String getRemoteHost()
// 獲取協議
String getScheme()
3. Request物件獲取請求頭

request.getHeader("頭名稱");
Referer: 該請求頭可以顯示本次請求來源於哪裡
如果是在瀏覽器位址列直接訪問, 那麼request.getHeader(“referer”)
得到的是null
User-agent: 表示瀏覽器的資訊(我的瀏覽器是Chrome)

resp.getWriter().print(req.getHeader("User-Agent"));
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
4. request的請求轉發和請求包含

轉發特點:
a. 轉發一共只有一次請求
b. 轉發不會改變瀏覽器位址列的地址
c. 轉發只能轉發給本應用的資源
d. 在轉發過程中ServletDemo1(傳送請求的Servlet)不能有響應體, 只能有響應頭

包含:
在包含中兩個Servlet都可以有響應體, 其它一樣

5. request物件作為Java Web四大域物件之一使用

request作為域物件的方法:

        setAttribute(name, value); // 儲存資料
        getAttribute(name); // 獲取資料
        removeAttribute(name); // 刪除資料

Request物件只作用在一次請求中, Request物件在傳送請求的時候產生,
在請求結束後銷燬, 只有在轉發和包含中才能使用request傳輸資料.

注意: 轉發不需要帶專案名, 重定向需要帶專案名

request.getRequestDispatcher("/IncludeDemo2").include(request, response);
response.sendRedirect("/day_1_11/index.jsp");

其中亂碼問題的解決

伺服器向瀏覽器響應的時候為什麼會出現亂碼?
根本原因: 編碼和解碼的時候採用的碼錶不一致導致的
伺服器採用utf-8的格式編碼, 而瀏覽器採用預設的ISO-8859-1來解讀,
而ISO-8859-1不支援中文, 所以就亂碼.
那麼這個時候伺服器得告訴瀏覽器編碼格式, 讓瀏覽器採用該碼錶, 才不會出現亂碼.

響應亂碼解決

    response.setCharacterEncoding(“UTF-8”); //一般都是不使用的
    response.setContentType(“text/html;charset=UTF-8”); //一般使用這個

亂碼解決:
post提交 請求亂碼解決
request.setCharacterEncoding("UTF-8");

get提交 請求亂碼解決
兩種方法:
1. 修改Tomcat配置檔案server.xml
加上URIEncoding="utf-8"
server.png

  1. 不管客戶端採用什麼編碼格式, 伺服器都會使用ISO-8859-1來解碼
    那麼我們只需要重新使用ISO-8859-1進行編碼, 然後再通過UTF-8進行解碼, 即可解決亂碼問題

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "utf-8");

補充

post和get請求的區別?
get請求:
1. 表單的預設請求方式, 超連結, location.href, 定時重新整理,
瀏覽器直接訪問, 重定向都是get提交
2. get提交如果帶引數, 引數只能繫結在url路徑上, 引數洩露,
不安全
3. url路徑最大隻能是1kb, 那麼對於get提交的引數具有長度的限制
4. 對於get提交的引數解決亂碼, 需要重新編碼再解碼, 比較麻煩

Post提交:
1. 只有明確給出了form表單的method屬性為post時候, 才是post提交
2. post提交的引數不需要繫結在url路徑上, 它有專門的請求體, 更安全,
引數長度更大
4. Post提交處理亂碼只需要
request.setCharacterEncoding("utf-8"), 處理比較方便

完整程式碼地址