Servlet實戰(3)
Servlet實戰(3)
在Servlet(1)和Servlet(2)中自己收穫了很多,每一篇筆記都是自己的親身實踐,在Servlet(3)中我會繼續探索一些讓我迷惑的東西。在Servlet學習結束後,我將開始深入的探索struts框架,一步步走下去。
請求轉發----------getRequestDispatcher()
頁面重定向、請求轉發
我記得我剛開始接觸java時,那時候跟傻子一樣,學什麼東西都是狼吞虎嚥,現在回想起來,當初的知識十有七八都忘了,腦海裡只留下一點影,遇到問題知道百度哪些。現在再來細細學習當初讓自己迷惑的東西。
推薦好文:https://www.cnblogs.com/understander/p/5689900.html
說實在的,看了上面推薦的好文之後,我就不想寫這個重定向和轉發了,因為感覺他裡面講的很好,很透徹。自己就把原文抄一遍,加深印象吧【轉載】。
重定向----------sendRedirect()
介紹
Servlet相應請求有兩種方式,一個是重定向,返回一個頁面給客戶端,另一種是直接向客戶端傳遞資料。
使用重定向是讓瀏覽器重新發送請求,它可以請求是當前站點下的一個Servlet,也可以是當前站點下的其他靜態檔案,如果是其他站點下的記得寫全位址列資訊(加http)。
使用方式
response.sendRedirect("/ServletProject/DemoServlet")
官網說明
【使用指定的重定向位置URL向客戶端傳送臨時重定向響應並清除緩衝區。緩衝區將被此方法設定的資料替換。呼叫此方法將狀態程式碼設定為sc_found 302(found)。此方法可以接受相對URL;servlet容器必須在將響應傳送到客戶端之前將相對URL轉換為絕對URL。如果位置是相對的,而沒有前導“/”,則容器將其解釋為相對於當前請求URI。如果位置與前導“/”相關,則容器將其解釋為相對於servlet容器根。如果已提交響應,則此方法將引發IllegalStateException。使用此方法後,應將響應視為已提交,而不應寫入。】
例子
來看一個例子:
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/RedirectServlet") public class RedirectServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); // 位址列變成:http://localhost:8080/Servlet/www.taobao.com // resp.sendRedirect("www.taobao.com"); // 位址列變成:http://localhost:8080/www.taobao.com // resp.sendRedirect("/www.taobao.com"); // 位址列變成:https://www.taobao.com/ // resp.sendRedirect("http://www.taobao.com"); // 重定向到其他站點要使用絕對URL // 將請求重定向到index.jsp // resp.sendRedirect("index.jsp"); req.setAttribute("name", "毛毛"); // 將請求重定向到Servlet resp.sendRedirect("Redirect_DispatcherServlet"); } }
從位址列的變化中我們可以看出,重定向可以重定向到當前站點下某一個專案裡的其他Servlet,也可以重定向到另一個專案裡的其他Servlet,或者是其他站點的專案。
@WebServlet("/Redirect_DispatcherServlet") public class Redirect_DispatcherServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("name:"+req.getAttribute("name")); } }
請求轉發----------getRequestDispatcher()
介紹
將客戶端的請求轉發到另一個Servlet或者JSP頁面。
使用方式
request.getRequestDispatcher("/").forward(request, response);
官網說明
【返回一個RequestDispatcher物件,該物件用作位於給定路徑的資源的包裝器。RequestDispatcher物件可用於將請求轉發到資源或在響應中包含資源。資源可以是動態的或靜態的。指定的路徑名可能是相對的,儘管它不能擴充套件到當前servlet上下文之外。如果路徑以“/”開頭,則被解釋為相對於當前上下文根目錄。如果servlet容器無法返回requestDispatcher,則此方法返回空值。此方法與servletContext getRequestDispatcher的區別在於,此方法可以採用相對路徑。】
例子
來看一個例子:
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/DispatcherServlet") public class DispatcherServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 請求到首頁 // req.getRequestDispatcher("/index.jsp").forward(req, resp); // 也能請求到首頁 // req.getRequestDispatcher("index.jsp").forward(req, resp); req.setAttribute("name", "毛毛"); req.getRequestDispatcher("/Redirect_DispatcherServlet").forward(req, resp); } }
兩者之間的區別
區別
(1)RequestDispatcher.forward方法只能將請求轉發給同一個WEB應用中的元件;而HttpServletResponse.sendRedirect方法不僅可以重定向到當前應用程式中的其他資源,還可以重定向到同一個站點上的其他應用程式中的資源,甚至是使用絕對URL(帶有http)重定向到其他站點的資源。如果傳遞給HttpServletResponse.sendRedirect方法的相對URL以“/”開頭,它是相對於整個WEB站點的根目錄;如果建立RequestDispatcher物件時指定的相對URL以“/”開頭,它是相對於當前WEB應用程式的根目錄。
(2)呼叫HttpServletResponse.sendRedirect方法重定向的訪問過程結束後,瀏覽器位址列中顯示的URL會發生改變,由初始的URL地址變成重定向的目標URL;而呼叫RequestDispatcher.forward方法的請求轉發過程結束後,瀏覽器位址列保持初始的URL地址不變。
(3)HttpServletResponse.sendRedirect方法對瀏覽器的請求直接作出響應,響應的結果就是告訴瀏覽器去重新發出對另外一個URL的訪問請求。RequestDispatcher.forward方法在伺服器端內部將請求轉發給另外一個資源,瀏覽器只知道發出了請求並得到了響應結果,並不知道在伺服器程式內部發生了轉發行為。
重定向發兩次請求,位址列改變了,兩次是不同的request請求。
轉發只發一次請求,位址列不變,轉發方和接收方共享req和resp物件,所以能拿到name
(4)RequestDispatcher.forward方法的呼叫者與被呼叫者之間共享相同的request物件和response物件,它們屬於同一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法呼叫者與被呼叫者使用各自的request物件和response物件,它們屬於兩個獨立的訪問請求和響應過程。對於同一個WEB應用程式的內部資源之間的跳轉,特別是跳轉之前要對請求進行一些前期預處理,並要使用HttpServletRequest.setAttribute方法傳遞預處理結果,那就應該使用RequestDispatcher.forward方法。不同WEB應用程式之間的重定向,特別是要重定向到另外一個WEB站點上的資源的情況,都應該使用HttpServletResponse.sendRedirect方法。
(5)無論是RequestDispatcher.forward方法,還是HttpServletResponse.sendRedirect方法,在呼叫它們之前,都不能有內容已經被實際輸出到了客戶端。如果緩衝區中已經有了一些內容,這些內容將被從緩衝區中清除。
總結
轉發-----你找我借錢,我沒錢,但是我可以幫你去找別人借錢。(再“借錢”這個動作由我去執行)
重定向-----你找我借錢,我沒錢,但是我讓你去找別人借錢。(再“借錢”這個動作由你自己去執行)
接下來要讀的是
JSP的基本構成