HTTP協議基礎與web服務的重定向,跳轉以及請求轉發

  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");

  最後總結一下請求轉發的特色:

  • 請求路徑沒有改變,但能夠涉及服務器端多個資源
  • 能夠在一次請求中,共享request做用域的數據
  • 一次請求,使用請求轉發,tomcat將建立兩個request和一個response對象,兩個request對象數據相同的(能夠理解成對象被克隆了)
相關文章
相關標籤/搜索