本文對 request、 response 簡單描述,未涉及到具體的瀏覽器緩存、重定向、請求轉發等代碼部分。
一、Web服務器,瀏覽器,代理服務器
在看 response、request 對象之前,先來了解一下 Web服務器,瀏覽器,代理服務器 三者之間的關系。
當我們打開瀏覽器,在地址欄中輸入URL,然后我們就看到了網頁。 原理是怎樣的呢?
實際上我們輸入 URL 后,我們的瀏覽器給Web服務器發送了一個 Request, Web 服務器接到Request 后進行處理,生成相應的 Response,然后發送給瀏覽器, 瀏覽器解析 Response 中的 HTML,這樣我們就看到了網頁,過程如下圖所示:

我們的 Request 有可能是經過了代理服務器,最后才到達 Web 服務器的。
過程如下圖所示:

代理服務器就是網絡信息的中轉站,有什么功能呢?
-
提高訪問速度, 大多數的代理服務器都有緩存功能。
-
突破限制, 也就是FQ了
-
隱藏身份。
二、再回過頭看 response、request 對象
Tomcat(Web應用服務器) 收到客戶端的 http 請求,會針對每一次請求,分別創建一個代表請求的 request 對象、和代表響應的 response 對象。
如上,我們想拿到用戶發送過來的數據,只需要找到 request 對象;而響應用戶請求,則找 response 對象。

我們在程序中經常看到如下兩個對象,這就是我們要找的 request、response
2.1 HttpServletResponse
HttpServletResponse 封裝了 response 對象,通過該對象實現向瀏覽器輸出數據,實現交互。
2.1.1 常見方法:
addCookie(Cookie cookie) 向客戶端寫入Cookie
addHeader(Java.lang.String name, java.lang.String value) 寫入給定的響應頭
encodeURL(java.lang.Stringurl) 默認cookie中包含Session ID,如果客戶端不支持 Cookie,就在參數 url 中加入 Session ID 信息,可以解決用戶禁用cookie的問題。
setStatus(intsc) 設置響應的狀態碼。
2.1.2 實現向瀏覽器輸出
HttpServletResponse 實現向用戶輸出數據的方法:getOutputStream 和 getWriter方法
getOutputStream 和 getWriter 方法分別用於得到輸出二進制數據、輸出文本數據的ServletOuputStream、Printwriter對象。
getOutputStream 和 getWriter 這兩個方法互相排斥,調用了其中的任何一個方法后,就不能再調用另一方法。
getOutputStream() 方法例子:
調用 getOutputStream() 方法獲得 ServletOutputStream 流,再使用 print() 或 write() 向瀏覽器輸出數據。試驗一下:
//獲取到OutputStream流
ServletOutputStream servletOutputStream = response.getOutputStream();
//向瀏覽器輸出數據
servletOutputStream.print("niceyoo");
效果如下:

getWriter() 方法例子:
//獲取到printWriter對象
PrintWriter printWriter = response.getWriter();
printWriter.write("niceyoo-getWriter");
效果如下:

2.1.3 實現重定向
重定向指的是一個web資源收到客戶端請求后,web服務器通知客戶端去訪問另外一個web資源,這稱之為請求重定向。實現方式是調用response.sendRedirect()方法。實現的原理就是給客戶端返回了302狀態碼和location頭。
2.2 HttpServletRequest
HttpServletRequest 封裝了 request對象,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中。
2.2.1 常見方法:
獲得客戶端的信息:
getRequestURL 方法返回客戶端發出請求時的完整URL。
getRequestURI 方法返回請求行中的資源名部分,去掉主機名的部分。
getRemoteAddr 方法返回發出請求的客戶機的IP地址
getRemoteHost 方法返回發出請求的客戶機的完整主機名
getRemotePort 方法返回客戶機所使用的端口號
getLocalAddr 方法返回WEB服務器的IP地址。
getLocalName 方法返回WEB服務器的主機名
getMethod 得到客戶機請求方式,如GET,POST
--
獲得請求頭的方法:
getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法
--
獲得請求參數:
getParameter(name)方法
getParameterValues(String name)方法
getParameterNames方法
getParameterMap方法
2.2.2 實現轉發
請求轉發指一個 web 資源收到客戶端請求后,通知服務器去調用另外一個web資源進行處理。request 對象提供了一個 getRequestDispatcher 方法,該方法返回一個RequestDispatcher 對象,調用這個對象的 forward 方法可以實現請求轉發。
2.2.3 request域
request 對象同時也是一個域對象,我們通過 request 對象在實現轉發時,可以把數據通過request 對象帶給其它web資源處理。
下面是常用的一些對域中的屬性的操作的方法:
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
2.2.4 Request的getParameter和getAttribute方法
由於 request 也是一個域對象,所以既可以從它獲得參數,即 Parameter。也可以獲得域中的屬性。但是他們的意義是完全不一樣的。
getParameter(String name):獲得客戶端傳送給服務器的參數值,該參數是由 name 指定的,通常是表單中的參數。而且參數只能是字符串形式的鍵值對。
getAttribute(String name):返回有name 指定的屬性值,如果指定的屬性值不存在,則會返回一個null值。這里存放的也是一個鍵值對,不同的是,這里的值可以是任意的類型。
三、總結
Web 服務器收到客戶端的 http 請求,會針對每一次請求,分別創建一個用於代表請求的 request 對象、和代表響應的 response 對象。
也就是一次請求生成一個 request 和 response,如果客戶端和服務器握手結束,request 和 response 則是一起隨着握手的消失而消失。
在程序中,與瀏覽器交互是通過 request、response 這連個對象進行的,request 封裝了用戶的請求數據,response 則用於向瀏覽器輸出數據。
如果文章有錯的地方歡迎指正,大家互相留言交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:niceyoo
