Servlet跳轉方式sendReDirect()和forward()

在web應用服務中,常常會面對不一樣SERVLET之間的跳轉,目前咱們能夠經過如下兩種方式實現: html

1.RequestDispatcher.forward() java

2.ServletResponse.sendReDirect() web

 

二者的區別: 緩存

1.redirect 方式能夠跨應用訪問,forward 只能在同一個應用中跳轉。 服務器

2.forward 客戶端訪問服務器,服務器找到要跳轉的相應URL並執行返回給客戶端。客戶端的地址欄顯示的是原始URLjsp

   redirect 客戶端訪問服務器,服務器找到要跳轉的URL並將URL發給客戶端,再由客戶端對新的URL從新發送請求。客 this

   戶端的地址欄顯示的是第二次請求的URLurl

3.數據的傳輸:在request中的數據,forward能夠訪問,redirect不行,由於redirect已是一個新的請求。 spa

 

forward跳轉的理解: 線程

1.得到跳轉

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")。

 

Java代碼   收藏代碼
  1. request.getRequestDispatcher("/uu").forward(request,response)  
  2.   
  3. this.getServletContext().getRequestDispatcher("/uu").forward(request,response)  
  4.   
  5. this.getServletContext().getNamedDispatche("ServletName").forward(request, response)  

 

1.1 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調用中有效。

 

2 使用RequestDispatcher

要使用requestDispatcher,servlet能夠調用RequestDispatcher接口的include或forward方法。這些方法的參數能夠是經過Servlet接口的service方法傳遞的request和response參數,也能夠是規範2.3中引入的request和response包裝類的子類的實例。後者,包裝實例必須包裝容器傳遞給service方法的request和response對象。

 

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

 

3 include方法

RequestDispatcher接口的include能夠隨時調用。include方法的目標servlet能夠完整訪問request對象,可是使用response對象上有一些限制:

 

它只能向response對象的ServletOutputStream或者Writer寫入信息,提交響應(將內容輸出到響應緩衝尾部),或者顯式調用ServletResponse接口的flushBuffer方法。它不能設置header,或者調用任何影響響應header的方法。任何那樣的嘗試必須都被忽略。

 

3.1 包含的請求參數

除了使用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方法得到,那麼這些屬性沒有設置。

 

4 forward方法

RequestDispatcher接口的forward方法只有在輸出還未提交給客戶端時,才能夠由調用servlet調用。若是輸出數據存在於還未提交的響應緩衝中,內容必須在目標servlet的service方法調用以前清空 (不然out.println()輸出的都在緩存中,無效)。若是響應已被提交,必須拋出IllegalStateException異常。暴露給目標servlet的request對象的path元素必須映射用來得到RequestDispatcher的路徑。

惟一例外是若是RequestDispatcher是經過getNamedDispatcher方法得到的,這種狀況下,request對象的path元素必須必須映射最初的請求。

 

在RequestDispatcher接口的forward方法返回以前,servlet容器必須發送,提交併關閉響應內容。

 

Java代碼   收藏代碼
  1. public void doPost(HttpServletRequest request,HttpServletResponse response ) throws IOException,ServletException{  
  2. String page =  request.getParameter("page");//在forward時被URL中的page=1覆蓋了  
  3.         response.setCharacterEncoding("UTF-8");  
  4.         //clear cache.  
  5.         response.setHeader("Pragma","No-cache");            
  6.         response.setHeader("Cache-Control","no-cache");     
  7.         response.setHeader("Cache-Control""no-store");     
  8.         response.setDateHeader("Expires",0);  
  9.           
  10.         PrintWriter out = response.getWriter();  
  11.         out.println("<html>");  
  12.         out.println("<head><title>china</title></hea>");  
  13.         out.println("<body>");  
  14.         out.print("==");  
  15.         out.println("<br/>");//jsp頁面換行  
  16.         out.println("</body>");  
  17.         out.println("</html>");  
  18.           
  19.         //若是out.flush或者out.close().表示響應已經提交,拋出異常IllegalStateException異常。requestDispather.forward():不會執行.  
  20.         //out.flush();  
  21.         //out.close();        
  22.         //跳轉方式3種.  
  23.     //  request.getRequestDispatcher("/productInfo.do?page=1").forward(request,response);  
  24. }  

 

 4.1 query字符串

請求轉發機制負責在轉發(forward)或包含(include)請求時傳遞query字符串。

 

5 錯誤處理

若是requesDispatcher的目標的servlet拋出ServletException或IOException類型運行時異常或checked異常,應當將它傳遞給調用servlet。全部其它異常應當包裝成ServletException異常,而且異常的根在傳遞以前設置爲原始異常。

 

 

相對路徑的理解:

forward中"/"相對於web應用.
http://localhost:8080/Test/gw/page.jsp中轉發
  <jsp:forward page="OtherPage.jsp"/>在JSP頁面被解析後轉換成pageContext.forward("OtherPage.jsp");
  "/OtherPage.jsp"提交到http://localhost:8080/Test/OtherPage.jsp
  "OtherPage.jsp"提交到http://localhost:8080/Test/gw/OtherPage.jsp
  
  <form action="/ddd"> 和 response.sendRedirect("/ddd"); 相對於服務器根路徑.
  假設轉發代碼包含於註冊的servlet-url爲/ggg/tt;jsp爲/ggg/tt.jsp:
  絕對路徑:response.sendRedirect("http://www.brainysoftware.com")發送http://www.brainysoftware.com
  根路徑:response.sendRedirect("/ooo")發送至http://localhost:8080/ooo
  相對路徑:response.sendRedirect("ooo")發送至http://localhost:8080/Test/ggg/ooo,

相關文章
相關標籤/搜索