1. 程式人生 > >五十一、forward和redirect

五十一、forward和redirect

forward 和redirect

1. forward方法使用

request.getRequestDispatcher(path).forward(request.response);

首先來看getRequestDispatcher方法,path必須是相對路徑。

getRequestDispatcher

RequestDispatcher getRequestDispatcher(String path)

Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. A RequestDispatcher

 object can be used to forward a request to the resource or to include the resource in a response. The resource can be dynamic or static.

The pathname specified may be relative, although it cannot extend outside the current servlet context. If the path begins with a "/" it is interpreted as relative to the current context root. This method returns null

 if the servlet container cannot return a RequestDispatcher.

The difference between this method and ServletContext.getRequestDispatcher(java.lang.String) is that this method can take a relative path.

 

Parameters:

path - a String specifying the pathname to the resource. If it is relative, it must be relative against the current servlet.

Returns:

RequestDispatcher object that acts as a wrapper for the resource at the specified path, or null if the servlet container cannot return a RequestDispatcher

See Also:

RequestDispatcherServletContext.getRequestDispatcher(java.lang.String)

接著forward方法,

forward

void forward(ServletRequest request,
             ServletResponse response)
             throws ServletException,
                    IOException

Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response.

For a RequestDispatcher obtained via getRequestDispatcher(), the ServletRequest object has its path elements and parameters adjusted to match the path of the target resource.

forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.

The request and response parameters must be either the same objects as were passed to the calling servlet's service method or be subclasses of theServletRequestWrapper or ServletResponseWrapper classes that wrap them.

 

Parameters:

request - a ServletRequest object that represents the request the client makes of the servlet

response - a ServletResponse object that represents the response the servlet returns to the client

Throws:

ServletException - if the target resource throws this exception

IOException - if the target resource throws this exception

IllegalStateException - if the response was already committed

 

2.sendRedirect方法使用

HttpServletResponse中使用sendRedirect可以實現跳轉,可以接受相對路徑或者絕對路徑。

sendRedirect

public void sendRedirect(java.lang.String location)
                  throws java.io.IOException

Sends a temporary redirect response to the client using the specified redirect location URL. This method can accept relative URLs; the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading '/' the container interprets it as relative to the current request URI. If the location is relative with a leading '/' the container interprets it as relative to the servlet container root.

If the response has already been committed, this method throws an IllegalStateException. After using this method, the response should be considered to be committed and should not be written to.

 

引數

定位 - the redirect location URL

Throws:

java.io.IOException - If an input or output exception occurs

java.lang.IllegalStateException - If the response was committed or if a partial URL is given and cannot be converted into a valid URL

 

Servlet 跳轉 redirectforward跳轉的區別

Servlet:

當然,在servlet中,一般跳轉都發生在doGet, doPost等方法裡面。

一、原理

1) redirect 方式

response.sendRedirect("/a.jsp");

頁面的路徑是相對路徑。sendRedirect可以將頁面跳轉到任何頁面,不一定侷限於本web應用中,如:

response.sendRedirect("http://www.ycul.com");

跳轉後瀏覽器位址列變化。

這種方式要傳值出去的話,只能在url中帶parameter或者放在session中,無法使用request.setAttribute來傳遞。

這種方式是在客戶端作的重定向處理。該方法通過修改HTTP協議的HEADER部分,對瀏覽器下達重定向指令的,讓瀏覽器對在location中指定的URL提出請求,使瀏覽器顯示重定向網頁的內容。該方法可以接受絕對的或相對的URLs。如果傳遞到該方法的引數是一個相對的URL,那麼Web container在將它傳送到客戶端前會把它轉換成一個絕對的URL。public void doPost(HttpServletRequest request,HttpServletResponse response)    throws ServletException,IOException

{

        response.setContentType("text/html; charset=UTF-8");

        response.sendRedirect("/index.jsp");

}

2) forward方式

RequestDispatcher dispatcher = request.getRequestDispatcher("/a.jsp");

dispatcher .forward(request, response);

頁面的路徑是相對路徑。forward方式只能跳轉到本web應用中的頁面上。

跳轉後瀏覽器位址列不會變化。

使用這種方式跳轉,傳值可以使用三種方法:url中帶parameter,session,request.setAttribute

這種方式是在伺服器端作的重定向。伺服器往client傳送資料的過程是這樣的:伺服器在向客戶端傳送資料之前,是先將資料輸出到緩衝區,然後將緩衝區中資料傳送給client端。什麼時候將緩衝區裡的資料傳送給client端呢?(1)當對來自client的request處理完,並把所有資料輸出到緩衝區,(2)當緩衝區滿,(3)在程式中呼叫緩衝區的輸出方法out.flush()或response.flushbuffer(),web container才將緩衝區中的資料傳送給client。

這種重定向方式是利用伺服器端的緩衝區機制,在把緩衝區的資料傳送到客戶端之前,原來的資料不傳送,將執行轉向重定向頁面,傳送重定向頁面的資料,重定向呼叫頁的資料將被清除。如果在<JSP:FORWORD>之前有很多輸出,前面的輸出已使緩衝區滿,將自動輸出到客戶端,那麼這種重定向方式將不起作用,這一點應該特別注意。

public void doPost(HttpServletRequest request,HttpServletResponse response)   throws ServletException,IOException

{

        response.setContentType("text/html; charset=UTF-8");

        ServletContext sc = getServletContext();

        RequestDispatcher rd = null;

        rd = sc.getRequestDispatcher("/index.jsp");

        rd.forward(request, response);

}

二、區別.

1、forward重定向是在容器內部實現的同一個Web應用程式的重定向,所以forward方法只能重定向到同一個Web應用程式中的一個資源,重定向後瀏覽器位址列URL不變,而sendRedirect方法可以重定向到任何URL, 因為這種方法是修改http頭來實現的,URL沒什麼限制,重定向後瀏覽器位址列URL改變。

2、forward重定向將原始的HTTP請求物件(request)從一個servlet例項傳遞到另一個例項,而採用sendRedirect方式兩者不是同一個application。

3、基於第二點,引數的傳遞方式不一樣。forward的form引數跟著傳遞,所以在第二個例項中可以取得HTTP請求的引數。sendRedirect只能通過連結傳遞引數,response.sendRedirect(“login.jsp?param1=a”)。

4、sendRedirect能夠處理相對URL,自動把它們轉換成絕對URL,如果地址是相對的,沒有一個‘/’,那麼Web container就認為它是相對於當前的請求URI的。比如,如果為response.sendRedirect("login.jsp"),則會從當前servlet 的URL路徑下找login.jsp: http://10.1.18.8:8081/dms/servlet/Servlet 重定向的URL: http://10.1.18.8:8081/dms/servlet/login.jsp,如果為response.sendRedirect("/login.jsp")則會從當前應用徑下查詢url:http://10.1.18.8:8081/login.jsp。而forward不能這樣處理相對路徑。

java

他們的區別是:

response.sendRedirect是向客戶瀏覽器傳送頁面重定向指令,瀏覽器接收後將向web伺服器重新發送頁面請求,所以執行完後瀏覽器的url顯示的是跳轉後的頁面。跳轉頁面可以是一個任意的url(本伺服器的和其他伺服器的均可)。

RequestDispatcher.forward則是直接在伺服器中進行處理,將處理完後的資訊傳送給瀏覽器進行顯示,所以完成後在url中顯示的是跳轉前的頁面。在forward的時候將上一頁面中傳送的request和response資訊一同傳送給下一頁面(而response.sendRedirect不能將上一頁面的request和response資訊傳送到下一頁面)。由於forward是直接在伺服器中進行處理,所以forward的頁面只能是本伺服器的。

JSP:

1) response.sendRedirect();

和servlet的response.sendRedirect()方式一樣。

此語句前不允許有out.flush(),如果有,會有異常:

java.lang.IllegalStateException: Can't sendRedirect() after data has committed to the client.

at com.caucho.server.connection.AbstractHttpResponse.sendRedirect(AbstractHttpResponse.java:558)

...

跳轉後瀏覽器位址列變化

如果要跳到不同主機下,跳轉後,此語句後面的語句會繼續執行,如同新開了執行緒,但是對response的操作已經無意義了;

如果要跳到相同主機下,此語句後面的語句執行完成後才會跳轉;

2) response.setHeader("Location","");

此語句前不允許有out.flush(),如果有,頁面不會跳轉。

跳轉後瀏覽器位址列變化

此語句後面的語句執行完成後才會跳轉

3) <jsp:forward page="" />

此語句前不允許有out.flush(),如果有,會有異常:

java.lang.IllegalStateException: forward() not allowed after buffer has committed.

at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:134)

at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:101)

at com.caucho.jsp.PageContextImpl.forward(PageContextImpl.java:836)

...

跳轉後瀏覽器位址列不變,但是隻能跳到當前主機下

此語句後面的語句執行完成後才會跳轉