JavaWeb中,HttpServletRequest與HttpServletResponse幾乎是處理各類請求與操做必備的參數,與原始的ServletRequest/ServletResponse相比,它們符合HTTP協議,因此首先從http協議入手,回顧一些基本的內容,然後根據協議來總結經常使用的知識點。javascript
首先來介紹一下dos環境下簡單的http發送報文,接收報文的方法。運行輸入cmd,打開命令提示符輸入telnet 127.0.0.1 8080,回車後會出現一個輸入界面,但此時輸入的字符都沒法顯示,按住‘Ctrl+]’,出現Microsoft Telnet> 再按回車,進入到該界面後,能夠看到輸入的字符能夠顯示。css
----------------------------------------------------------------------------------------------->html
http協議基本內容:java
版本:1.0一次連接,一次請求;1.1一次連接,屢次請求得到不一樣的資源。web
----------------------------------------------------------------------------------------------->apache
請求分爲請求行,請求頭和請求體,根據請求方法的不一樣,可分爲七種,經常使用的爲GET, POST請求。請求行位於整個報文的第一行,包括"請求方式 資源路徑 協議",如:GET /demo/1.html?username=jack&password=1234 HTTP/1.1。請求內容會根據請求方式的不一樣而差別巨大,若是是GET請求,會以url拼接的形式放在請求行中資源路徑的後面,用"?"與"&"組合分割,如:http://localhost:8080/demo/1.html?username=jack&password=1234 ;若是是POST請求,則會單獨講請求內容放入請求體中。因爲url的長度有限制,因此GET請求追加的內容也有限制,通常爲1024字節(1k),但POST的請求體大小沒有限制。跨域
請求頭的經常使用內容:瀏覽器
Accept: text/html,image/* --支持數據類型
Accept-Charset: ISO-8859-1 --字符集
Accept-Encoding: gzip --支持壓縮格式
Accept-Language:zh-cn --語言環境
Host: www.itheima.com:80 --訪問主機
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT --緩存時間
Referer: http://www.itcast.com/index.jsp --來自哪一個頁面、防盜鏈 – 若是沒有經過超連接訪問2.html返回null
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) 用戶數據
Cookie --表示cookie技術
Connection: close/Keep-Alive --連接狀態
Date: Tue, 11 Jul 2000 18:23:51 GMT --時間緩存
另外,MIME表示Multipurpose Internet Mail Extensions(多用途互聯網郵件擴展),包括如下常見內容:tomcat
格式:大類型/小類型;參數
大類型:分7類,表示互聯網全部資源。
Text:用於標準化地表示的文本信息,文本消息能夠是多種字符集和或者多種格式的;
Multipart:用於鏈接消息體的多個部分構成一個消息,這些部分能夠是不一樣類型的數據;
Application:用於傳輸應用程序數據或者二進制數據;
Message:用於包裝一個E-mail消息;
Image:用於傳輸靜態圖片數據;
Audio:用於傳輸音頻或者音聲數據;
Video:用於傳輸動態影像數據,能夠是與音頻編輯在一塊兒的視頻數據格式。
例如:
text/css css文件
text/html html文件
text/javascript js文件
image/* 全部圖片
image/jpeg jpg圖片
----------------------------------------------------------------------------------------------->
請求的響應也分爲響應行,響應頭以及響應體。格式爲:"協議/版本 狀態碼 狀態碼對應描述信息"。
狀態碼:
1xx: 服務器響應瀏覽器,數據正在發送中。通常使用不多。
2xx: 服務器響應瀏覽器已經正常結束。 經常使用:200 表示正常。
3xx: 服務器響應瀏覽器,請求尚未完成,須要瀏覽器進一步操做,來完成整個請求。
經常使用狀態碼:
302 (307):與響應頭location 結合完成頁面從新跳轉。
304:頁面讀取緩存
4xx: 服務器響應瀏覽器,瀏覽器操做有誤。
常見:404 頁面找不到。(通常請求頁面找不到表示用戶URL寫錯)
5xx: 服務器響應瀏覽器,服務器異常
響應頭:
Location: http://www.it315.org/index.jsp --跳轉方向
Server:apache tomcat --服務器型號
Content-Encoding: gzip --數據壓縮
Content-Length: 80 --數據長度
Content-Language: zh-cn --語言環境
Content-Type: text/html; charset=GB2312 --數據類型
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT --最後修改時間
Refresh: 1;url=http://www.it315.org --定時刷新
Content-Disposition: attachment; filename=aaa.zip --下載
Set-Cookie:SS=Q0=5Lb_nQ; path=/search
Expires: -1 --緩存
Cache-Control: no-cache --緩存
Pragma: no-cache --緩存
Connection: close/Keep-Alive --鏈接
Date: Tue, 11 Jul 2000 18:23:51 GMT --時間
----------------------------------------------------------------------------------------------->
以上屬於http的一些基本內容,在web服務中,兩個最經常使用到的參數HttpServletRequest以及HttpServletResponse都須要在深入理解該協議的基礎上才能靈活運用。此處咱們主要討論請求轉發的實現,理清重定向、頁面跳轉以及頁面刷新的過程。
重定向時,瀏覽器的請求到達服務器,服務器響應中有兩個必備的元素,一個是狀態碼:302,一個是重定向的地址,瀏覽器收到報文後,根據這兩個信息從新發送請求,到指定的Location;而頁面刷新是指,服務器在發送報文時,頭信息中包含了"refresh",使瀏覽器能夠按照延時刷新本頁面或者跳轉到指定URL;請求轉發,是瀏覽器請求服務器時,服務器內部跳轉到新的URL獲取到資源並在原來的頁面展現給瀏覽器的過程,根據轉發方法的不一樣分爲請求轉發與請求包含兩種。
兩種重定向的方式:
/** *方式一:更接近服務器響應瀏覽器的過程 */ response.setStatus(302) response.setHeader("location","http://www.changjiang.com/TestServlet"); /** *方式二:更爲簡便 */ response.sendRedirect("http://www.changjiang.com/TestServlet");
頁面刷新所須要攜帶的報文內容,其實這個使用的場景也是蠻多的:
/** * 跳轉 --兩次都是200 (有可能第二個304 讀取瀏覽器緩存) * 格式:秒 --> 指定秒數刷新當前頁面 * 格式:秒;url="" --> 指定秒以後跳轉到指定的url */ response.setHeader("refresh", "2"); response.setHeader("refresh", "0;url=1.html");
來看一些用到頁面刷新的實例:
private void test1(HttpServletResponse response) throws IOException { response.setHeader("refresh", "3"); String data = new Random().nextInt(100000)+""; response.getWriter().write(data); } private void test2(HttpServletResponse response) throws IOException { response.setHeader("refresh", "3;url='/day06/index.jsp'"); response.setContentType("text/html;charset=GB2312"); response.getWriter().write("登陸成功,將在3秒後跳轉,若是沒有,請點<a href='xxx'>超連接</a>"); }
最後看下服務器內部進行的請求轉發,首選要得到轉發的RequestDispatcher,
當前servlet路徑: http://localhost:8080/day08/a/b/Demo01Servlet 另外一個servlet路徑:http://localhost:8080/day08/a/b/Demo02Servlet ServletRequest (經常使用) request.getRequestDispatcher("Demo02Servlet") request.getRequestDispatcher("/a/b/Demo02Servlet") --注意:沒有day08 , (擴展:對比重定向) ServletContext this.getServletContext().getRequestDispatcher("/a/b/Demo02Servlet ")
接着須要指定請求轉發仍是請求包含:
forward(ServletRequest request, ServletResponse response) 請求轉發 A 轉發 B,只輸出B內容到瀏覽器。(若是A沒有數據發送 response.isComitted = false,將清空緩存) 請求轉發只輸出最後一個servlet內容 若是 isCommitted = true ,在進行forward將拋異常。通常狀況若是輸出少許的數據,認爲isCommitted=false include(ServletRequest request, ServletResponse response) 請求包含 A 包含 B,先輸出A內容到瀏覽器,在輸出B的內容到瀏覽器。 請求包含,輸出全部servlet 彙總後的內容。
在使用請求轉發時,一個request涉及到了多個servlet的資源,屬於跨域操做,須要特別注意各個資源內的編碼一致性,因此通常servlet中須要加入如下兩行代碼,保證資源編碼一致:
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
最後總結一下請求轉發的特色: