1. 程式人生 > >sendRedirect()與forward()實現轉向的區別

sendRedirect()與forward()實現轉向的區別

sendRedirect()與forward()

1.前面慢,後者快
2.前面無法讀取request.setAttribute()所儲存的數值,而後者可以讀取
3.前者位址列顯示真正轉向後的地址,而後者顯示的是轉向前的地址
4.前者,轉向地址開始的"/",表示的是本機的根目錄;而後者,"/"表示的是應用的根目錄

response.sendRedirect("/Test/admin/admin.jsp");
//---------------------------------------------------------------------

request.setAttribute("message", "您輸入的兩次新密碼不相符!");
request.getRequestDispatcher("/admin/Result.jsp").forward(request, response);

獲取RequestDispatcher

可以通過ServletContext的下列方法獲得實現RequestDispatcher介面的物件:

• getRequestDispatcher

• getNamedDispatcher

getRequestDispatcher方法以String引數描述ServletContext作用域的路徑。該路徑必須相對於ServletContext的根,並且以“/”開頭。該方法使用路徑(path)來查詢servlet,用RequestDispatcher物件包裝,然後返回結果物件。如果沒有基於指定路徑的servlet,提供一個RequestDispatcher返回路徑值。

getNamedDispatcher方法以String引數表示ServletContext已知的servlet名稱。如果找到servlet,用RequestDispatcher物件將它包裝並返回。如果沒有和指定名稱關聯的servlet,該方法必須返回null。

為了能夠使用當前請求的相對路徑(不是ServletContext根的相對路徑)來獲得RequestDispatcher物件,ServletRequest介面提供以下方法:

• getRequestDispatcher

該方法的行為和ServletContext的同名方法類似。servlet容器使用request物件中的資訊將指定的相對路徑轉換成完整路徑。比如,以“/”為根的上下文,請求/garden/tools.html,通過ServletRequest.getRequestDispatcher("header.html") 獲得的requestDispatcher實際上等同於呼叫ServletContext.getRequestDispatcher("/garden/header.html")。

 RequestDispatcher路徑的query字串

ServletContext和ServletRequest使用path引數建立RequestDispatcher物件的方法,允許在path後新增query字串。比如,開發人員可以通過下列程式碼獲得RequestDispatcher:

String path = “/raisons.jsp?orderno=5”;

RequestDispatcher rd = context.getRequestDispatcher(path);

rd.include(request, response);

query字串中指定的引數用來建立RequestDispatcher,優先於傳遞給包含servlet的同名的其他引數。該引數和RequestDispatcher關聯,只在include或forward呼叫中有效。

使用RequestDispatcher

要使用requestDispatcher,servlet可以呼叫RequestDispatcher介面的include或forward方法。這些方法的引數可以是通過Servlet介面的service方法傳遞的request和response引數,也可以是規範2.3中引入的request和response包裝類的子類的例項。後者,包裝例項必須包裝容器傳遞給service方法的request和response物件。

容器供應商必須確保向目標servlet轉發請求和原請求處於同一個VM,同一個執行緒。

 include方法

RequestDispatcher介面的include可以隨時呼叫。include方法的目標servlet可以完整訪問request物件,但是使用response物件上有一些限制:

它只能向response物件的ServletOutputStream或者Writer寫入資訊,提交響應(將內容輸出到響應緩衝尾部),或者顯式呼叫ServletResponse介面的flushBuffer方法。它不能設定header,或者呼叫任何影響響應header的方法。任何那樣的嘗試必須都被忽略。

 包含的請求引數

除了使用getNamedDispatcher方法獲得的servlet之外,include的servlet可以訪問呼叫它的路徑。設定以下請求屬性:

javax.servlet.include.request_uri

javax.servlet.include.context_path

javax.servlet.include.servlet_path

javax.servlet.include.path_info

javax.servlet.include.query_string

include的servlet的這些屬性通過request物件的getAttribute方法訪問。

如果include的servlet通過getNamedDispatcher方法獲得,那麼這些屬性沒有設定。

 forward方法

RequestDispatcher介面的forward方法只有在輸出還未提交給客戶端時,才可以由呼叫servlet呼叫。如果輸出資料存在於還未提交的響應緩衝中,內容必須在目標servlet的service方法呼叫之前清空。如果響應已被提交,必須丟擲IllegalStateException異常。

暴露給目標servlet的request物件的path元素必須對映用來獲得RequestDispatcher的路徑。

唯一例外是如果RequestDispatcher是通過getNamedDispatcher方法獲得的,這種情況下,request物件的path元素必須必須對映最初的請求。

在RequestDispatcher介面的forward方法返回之前,servlet容器必須傳送,提交併關閉響應內容。