討論它們的區(qū)別之前,先讓我們看下它們是怎樣被調用的?
Response.sendRedirect(redirect)
redirect="AccessGoalCharts.jsp?rcatID=3&rhaID=All_&doSearch=true”
實際上,container會將這個 redirect的 url字符串重新送到
Browser interface,相當于用戶重新在address欄中輸入了一個地址,赫赫,
這樣解釋簡單吧?
request.getRequestDispatcher("welcome.jsp").forward(request, response);
我們查一下web.xml,如果我們沒有找到相應的servlet mapping,那么這套
Request和response(也就是原來的browse interface)就被轉到 welcome.jsp
去處理了,welcome.jsp產生的html page也就被返回到了 response(也就是原來的browser interface).如果在web.xml當中我們找到了相應的 servlet mapping, 如下所示,
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/welcome.jsp</url-pattern>
</servlet-mapping>
那么這套request和response就被forward到了DemoServlet的 doGet或者 doPost去處理了,問題是,getRequestDispatcher為什么不改名字叫做 getURLDispatcher,這不是更加符合 由 web.xml控制的實際情況嗎?
Request.getRequestDispatcher(“welcome.jsp”).include(request,response)和 forward(request,response)的情況一模一樣,區(qū)別在于,這個response,也就是 Browse Interface在接收了welcome.jsp產生的html page以后(假設在 web,xml當中沒有相對應于 welcome.jsp的 servlet-mapping),還可以在這個response( browser interface)當中接收其他的html page,我測試過的代碼如下所示:
request.getRequestDispatcher("welcome.jsp").include(request, response);
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is " + request.getParameter("name"));
out.print(this.getClass());
out.println(", using the POST method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
好了,還有一些考試大全中經常描述的 forward對于 用戶來講是透明的,而 reDirect對于用戶來講是 在browser的地址欄中可見的講法,都是正確的講法.
好,我再用通俗的講法講解一下 sendRedirct, forward, include的區(qū)別 (基于 servlet api 2.2以上)
(1)response.sendRedirect(String location)
Sends a temporary redirect response to the client using the specified redirect location URL 實際上是給client返回一個臨時的response,里面也就一個url,告訴client,我現(xiàn)在已經處理完了你的request, 你應該進入這個URL,它會處理你的request了(這個request的內容您這個client可能就不太清楚了) (2)requestDispatcher.forward(request, response)
現(xiàn)在的servlet把控制權完全交給另外一個Servlet,這個servlet已經預先處理過的request和response也一并移交過去, 這個forward的過程實際上Client并不知道,是Server端的幾個servlet collaboration. (3)include又和 forward有什么區(qū)別呢?
赫赫, requestDispatcher.include(request, response) 好像沒有什么區(qū)別啊,include僅僅是include, 接收request的那個servlet (called servlet),它往printerWriter(或OutputStream, writer是寫文本 而stream是寫二進制)中寫的內容是 caller servlet往 printerWriter(或 outputStream)中寫的內容的一部分.而 requestDispatcher.forward(request, response)就不一樣了,calling servlet控制權完全交出去了, calling servlet 的response buffer中的東西都被清空了,所以如果你要 forward,就是轉移控制權的話, 你根本就不應該在calling servlet 中的response里面寫任何東西,寫了的話一旦 forward的話也就白瞎了,因為被清空了嘛. (4)為什么 request.getRequestDispatcher 而 response.sendRedirect(new_url)呢?
我舉個簡單的例子, request.getRequestDispatcher("/servlets/bookItems?bookId=18871"); 赫赫,在 getRequestDispatcher的同時還可以往 request當中塞一個parameter啊. 而response.sendRirect(new_url)呢, 這個new_url可是會返回給client browser看的,所以 當然是response.sendRedirect(new_url)了. Servlet中forward和redirect的區(qū)別
forward方式:request.getRequestDispatcher("/somePage.jsp").forwardrequest, response); -------------------------------------------------------------------------------------------------- 在Java Web開發(fā)中,經常會用到跳轉頁面的方法,一般有下面兩種方法。 -------------------------------------------------------------------------------------------------- 清空當前緩存: 在之前撰寫JSP的例子中,實用了out這個對象,這個對象您不用事先宣告,就可以在JSP網頁中使用,這是JSP所提供的隱含對象 (Implicit Object),在轉譯為Servlet之后,out會轉換為對應于javax.servlet.jsp.JspWriter型態(tài)的對象。 JspWriter直接繼承自java.io.Writer,您可以使用println()、print()方法將指定的數(shù)據以字符的方式傳送至客戶端,println()會 在送出數(shù)據之后進行換行,而print()則否,注意換行指的是在HTML原始碼中設定換行字符,而不是輸出<br>標簽使得在網頁中可以 換行。 out(JspWriter)具有緩沖區(qū)功能,HTTP的特性是為了要取得一份資源,就進行一份協(xié)議溝通,如果資源數(shù)目很多(例如一份HTML文件 還包括了許多的小圖片),而每份資源的容量實際上很小,那么為了要取得完整的資源,將會花費很多通訊在協(xié)議往來上,假設如果 out(JspWriter)不具有緩沖功能,則每一次out.println(),就會直接將數(shù)據送出至客戶端,那么單要完成一個完整網頁的傳送,就 會花費不少的網絡資源,每一個JSP網頁預設上都會具有緩沖,您可以使用page指令元素的autoFlush屬性來設定是否使用緩沖區(qū)功能 。 在Tomcat5上,預設為每一個JSP網頁備有8192字節(jié)的緩沖區(qū)(您可以使用page指令元素的buffer屬性來自緩沖區(qū)的大小),在緩沖區(qū)還 沒有滿之前,數(shù)據不會真正被送出至客戶端,在這之前,您還有機會重設送出的數(shù)據,如果緩沖區(qū)滿了,數(shù)據將會被清出并送至客戶 端,可以使用下面這個程序來示范: buffer.jsp 您可以使用flush()直接清出緩沖區(qū)的內容,而clearBuffer()會將緩沖區(qū)的內容清除,所以第二段文字不會出現(xiàn)在客戶端的網頁上, 而最后一段會整個JSP網頁執(zhí)行完整后自動送出至客戶端,執(zhí)行結果如下: 預設緩沖區(qū)大?。?192 這段您可以看到! 您可以使用page指令元素的autoFlush來設定JSP頁面是否使用緩沖區(qū)自動清出功能,out(JspWriter)以一種方式與 HttpServletResponse的PrintWriter建立關系,兩者之間的行為關系取決于是否使用緩沖區(qū)自動清出,如果使用緩沖區(qū)自動清出,則 在緩沖區(qū)滿之前,或是使用flush()之前不會建立PrintWriter對象來對客戶端進行輸出,如果不使用緩沖區(qū)自動清出,則寫入out (JspWriter)對象的數(shù)據會直接寫入PrintWriter對象,然后在指定flush()之后輸出至客戶端。 如果您將autoFlush設定為false,則您必須明確的使用flush()來輸出數(shù)據,否則緩沖區(qū)滿了的話,就會發(fā)生IOException例外,使用 緩沖區(qū)有其好處,但由于緩沖區(qū)在滿之前,數(shù)據并不會真正送出客戶端,所以會有響應延遲的問題,如果您要實時性將結果響應至客 戶端,則可以關閉緩沖區(qū)。 下面這個程序測試緩沖區(qū)關閉之后,如果緩沖區(qū)滿了,會有什么結果: buffer.jsp 如果沒有移開out.flush()的批注符號,則會響應一下的錯誤訊息: |
|