Servlet--轉發和重定向


  • Servlet的跳轉有2種,一種是轉發,一種是重定向。

重定向:
<strong><span style="font-size:14px;"></span></strong><pre name="code" class="java"><strong style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);"><span style="font-size:14px;"></span></strong><pre name="code" class="java" style="display: inline !important;">httpServletResponse.sendRedirect("/linkin/Linkin.jsp");
 
        
 轉發: 
        
httpServletRequest.getRequestDispatcher("/Linkin.jsp").forward(httpServletRequest, httpServletResponse);
在jsp中,也經常用到轉發。
<jsp:forward page="Linkin.jsp" />

  • 在對比整理這2種Servlet之前,我們先來看下RequestDispatcher這個接口。
RequestDispatcher接口,定義一個對象,從客戶端接收請求,然后將它發給服務器的可用資源(例如Servlet、CGI、HTML文件、JSP文件)。Servlet引擎創建request dispatcher對象,用於封裝由一個特定的URL定義的服務器資源。這個接口是專用於封裝Servlet的,但是一個Servlet引擎可以創建request dispatcher對象用於封裝任何類型的資源。request dispatcher對象是由Servlet引擎建立的,而不是由Servlet開發者建立的。注意這里說了很清楚了,你不是我們創建的,所以我只管用就OK了。

RequestDispatcher接口中定義了兩個方法:forward方法(頁面跳轉)和include方法(頁面包含,不怎么常用)。 

forward和include方法接收的兩個參數必須是傳遞給當前Servlet的service方法的那兩個ServletRequest和ServletResponse對象,或者是對它們進行了包裝的ServletRequestWrapper 或ServletResponseWrapper對象。 


獲取RequestDispatcher對象的方法:
ServletContext.getRequestDispatcher (參數只能寫絕對路徑,以“/”開頭)
ServletRequest.getRequestDispatcher (參數可以是絕對路徑,也可以是相對路徑)
關於轉發和重定向,還有表單提交,超鏈接這些路徑到底怎么寫,后面我會專門整理一篇博客,這里不做贅述。


  • OK,現在來對比整理轉發和重定向。
1,轉發和重定向區別

轉發過程:客戶瀏覽器發送http請求----》web服務器接受此請求--》調用內部的一個方法在容器內部完成請求處理和轉發動作----》將目標資源發送給客戶。在這里,轉發的路徑必須是同一個web容器下的url,其不能轉向到其他的web路徑上去,中間傳遞的是自己的容器內的request。在客戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感覺不到服務器做了轉發的。

重定向過程:客戶瀏覽器發送http請求----》web服務器接受后發送302狀態碼響應及對應新的location給客戶瀏覽器--》客戶瀏覽器發現是302響應,則自動再發送一個新的http請求,請求url是新的location地址----》服務器根據此請求尋找資源並發送給客戶。在這里location可以重定向到任意URL,既然是瀏覽器重新發出了請求,則就沒有什么request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的路徑,客戶可以觀察到地址的變化的。


具體的區別如下:
1,轉發是服務器行為,重定向是客戶端行為。
2,轉發是瀏覽器只做了一次訪問請求。重定向是瀏覽器做了至少兩次的訪問請求的。
3,轉發瀏覽器地址不變,重定向瀏覽器地址改變。
4,轉發2次跳轉之間傳輸的信息不會丟失,重定向2次跳轉之間傳輸的信息會丟失(request范圍)。
5,轉發只能將請求轉發給同一個WEB應用中的組件,重定向可以指向任何的資源,包括當前應用程序中的其他資源,同一個站點上的其他應用程序中的資源,其他站點的資源。
注意:傳遞給HttpServletResponse.sendRedirect 方法的相對URL以“/”開頭,它是相對於整個WEB站點的根目錄;如果創建RequestDispatcher 對象時指定的相對URL以“/”開頭,它是相對於當前WEB應用程序的根目錄。
6,無論是RequestDispatcher.forward 方法,還是HttpServletResponse.sendRedirect 方法,在調用它們之前,都不能有內容已經被實際輸出到了客戶端。如果緩沖區中已經有了一些內容,這些內容將被從緩沖區中清除。

  • 怎么選擇是重定向還是轉發呢?
1,因為瀏覽器還得發出一個新的請求,重定向的速度比轉發慢,所以如果在使用轉發和重定向都無所謂的時候建議使用轉發。
2,因為重定向方式產生了一個新的請求,所以經過一次重定向后,request內的對象將無法使用,所以對於同一個WEB應用程序的內部資源之間的跳轉,特別是跳轉之前要對請求進行一些前期預處理,並要使用 HttpServletRequest.setAttribute 方法傳遞預處理結果,這個時候就只能使用轉發了。
3,因為轉發只能訪問別的應用程序,所以不同WEB應用程序之間的重定向,特別是要重定向到另外一個WEB站點上的資源的情況,這個時候就只能使用重定向了。
4,因為使用轉發,瀏覽器中URL仍然指向開始頁面,此時如果重載當前頁面,開始頁面將會被重新調用。如果你不想看到這樣的情況,則選擇重定向。


最后貼出2段代碼,演示下轉發,重定向。
package linkin;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author LinkinPark
 * @author 2015-7-8
 * @Descri 轉發
 */
public class LinkinServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		req.setCharacterEncoding("UTF-8");
		String userName = req.getParameter("userName");
		String passWord = req.getParameter("passWord");
		req.setAttribute("userName", userName);
		req.getSession().setAttribute("passWord", passWord);
		req.getRequestDispatcher("/Linkin.jsp").forward(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		this.doGet(req, resp);
	}

}

package linkin;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author LinkinPark
 * @author 2015-7-8
 * @Descri 重定向
 */
public class LinkinServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		req.setCharacterEncoding("UTF-8");
		String userName = req.getParameter("userName");
		String passWord = req.getParameter("passWord");
		req.setAttribute("userName", userName);
		req.getSession().setAttribute("passWord", passWord);
		resp.sendRedirect("/linkin/Linkin1.jsp");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		this.doGet(req, resp);
	}

}




免責聲明!

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



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