轉發和重定向簡介及與之相關的(URL)參數(parameter)、屬性(attribute)問題探討


 1.引子

        轉發和重定向是我們在做web項目中常用到的兩個術語,有必要理清兩者的區別和與之相關的參數、屬性獲取問題。

2.轉發和重定向

1).轉發

        轉發是服務器行為,將當前請求(Request)和響應(Response)處理打包發送給目標服務(Servlet),這樣下一個目標服務就能獲取或操作上一個服務中的請求和響應。

客戶瀏覽器發送http請求—>web服務器接受此請求—>調用內部的一個方法在容器內部完成請求處理和轉發動作—>將目標資源 發送給客戶

轉發行為是同一次請求,其URL地址仍是以前的地址,不會發生變化,但頁面內容卻是新頁面的東西了。轉發只能是在同一應用中使用,不能跨應用轉發請求,比如,京東頁面的請求就不可能轉發給淘寶的服務器。

2).重定向

        重定向就如其名字一樣,是將頁面定位到一個新位置。重定向客戶端行為,是全新的請求,客戶端不能保存當前的請求,在定位到新的頁面或servlet服務時,上次的請求超出請求的作用范圍了,那個請求即失效了。

客戶瀏覽器發送http請求—>web服務器接受后發送302狀態碼響應及對應新的location給客戶瀏覽器—>客戶瀏覽器發現 是302響應,則自動再發送一個新的http請求,請求url是新的location地址—>服務器根據此請求尋找資源並發送給客戶。

重定向至少是兩次請求,重定向后URL地址是新的地址了,當然頁面內容也更新為目標頁面的內容了。重定向可以定位到任意頁面,可以跨越不同的應用程序。比如,天貓的頁面就可以重定向到淘寶的頁面上。


參數(parameter)、屬性(attribute)的區別,可以看我另一篇帖子-----Servlet中的屬性(attribute)和參數(parameter)的區別

3.簡單示例

     登錄頁html代碼

<form action="loginServlet" method="post">
用戶名:
<input type="text" name="username" /> <br/>&nbsp;&nbsp;碼:
<input type="password" name="pwd"/><br/>
<!-- 默認的submit,提交給loginServlet處理 -->
<input type="submit" value="提交至將轉發的servlet"> <br/>
<!-- 一個表單內容可以提交給不同的servlet,而formaction屬性值就對應提交的目標地址,
這里提交給loginServlet2進行請求處理 -->
<input type="submit"  formaction="loginServlet2" value="提交至將重定向的servlet">
</form>

 

     要轉發的servlet

 @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String name=request.getParameter("username");
        String pwd=request.getParameter("pwd");
        System.out.println("用戶名:"+name+"\t密碼:"+pwd);
        //request域中設置一個屬性
        request.setAttribute("nowDate", new Date());
        //轉發
        request.getRequestDispatcher("forward_page.jsp?url_param=test_url_param").forward(request, response);
    }

 

     要重定向的servlet

  @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String name=request.getParameter("username");
        String pwd=request.getParameter("pwd");
        System.out.println("用戶名:"+name+"\t密碼:"+pwd);
        //request域中設置一個屬性
        request.setAttribute("nowDate", new Date());
        //重定向
        response.sendRedirect("redirect_page.jsp?url_param=test_url_param");
    }

 

     將轉發的登錄頁面

    轉發頁的html代碼

<body>
    <h3>這是一個轉發后的頁面</h3>
    request中獲取參數(用戶名):<label>${param.username}</label> <br/>
    request中獲取參數(密碼):<label>${param.pwd}</label> <br/>
    request中獲取的屬性(‘nowDate’):<label>${nowDate}</label> <br/>
    url中獲取的一個參數:<label>${param.url_param}</label> <br/>
  </body>

 

     servlet轉發到的頁面

    從上圖可以看出,所有的參數和屬性(包括url中拼接的參數)都可以正確地獲取,並顯示在頁面上。但url地址還是"loginServlet",不是當前頁面所對應的"forward_page.jsp"地址。

     將重定向的登錄頁面

重定向頁的HTML代碼

<body>
      <h3>這是一個重定向后的頁面</h3>
    request中獲取參數(用戶名):<label><c:out value="${param.username}" default="空"/></label> <br/>
    request中獲取參數(密碼):<label><c:out value="${param.pwd}" default="空"/></label> <br/>
    request中獲取屬性‘nowDate’:<label><c:out value="${nowDate}" default="空"/></label> <br/>
    url中獲取的一個參數:<label><c:out value="${param.url_param}" default="空"/></label> <br/>
  </body>

     servlet重定向到的頁面

       從上圖可以看出,上次請求的所有屬性、參數均不能獲取到。另外url地址更新了,不再是servlet的映射地址了,而當前新頁面的"redirect_page.jsp"地址。
除此之外,可以看到重定向的URL中拼接的鍵值對參數“url_param=test_url_param”在新頁面還是能獲取到的。

4.總結

       1.重定向,是一次新的請求,不能獲得上次請求中的參數、屬性;轉發,是同一次請求,之前所有的參數、屬性在新的頁面或servlet中都可見的,它們保存在同一個request域中。
       2.轉發操作,(即使轉至新頁面)其URL地址不會變化;而在重定向操作中,URL地址會更新變為重定向的目標地址。
       3.若要頁面內容、URL地址均更新,並且新頁面還要獲取上次請求的參數、屬性,可以通過一種曲線救國的方式實現:在重定向的URL中以鍵值對的方式來拼接上次請求的參數、屬性;並在新頁面中通過EL表達式“${param.name}”獲取。

 


免責聲明!

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



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