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


  JavaWeb中,HttpServletRequest與HttpServletResponse幾乎是處理各種請求與操作必備的參數,與原始的ServletRequest/ServletResponse相比,它們符合HTTP協議,所以首先從http協議入手,回顧一些基本的內容,而后根據協議來總結常用的知識點。

  首先來介紹一下dos環境下簡單的http發送報文,接收報文的方法。運行輸入cmd,打開命令提示符輸入telnet 127.0.0.1 8080,回車后會出現一個輸入界面,但此時輸入的字符都無法顯示,按住‘Ctrl+]’,出現Microsoft Telnet> 再按回車,進入到該界面后,可以看到輸入的字符可以顯示。

----------------------------------------------------------------------------------------------->

  http協議基本內容:

  版本:1.0一次鏈接,一次請求;1.1一次鏈接,多次請求獲得不同的資源。

----------------------------------------------------------------------------------------------->

  請求分為請求行,請求頭和請求體,根據請求方法的不同,可分為七種,常用的為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(多用途互聯網郵件擴展),包括以下常見內容:

  格式:大類型/小類型;參數
    大類型:分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對象數據相同的(可以理解成對象被克隆了)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM