servlet 轉發與重定向
重定向與轉發本質都是跳轉到新的URL
重定向與轉發的本質區別在於:轉發是一個服務端的行為,而重定向是一個瀏覽器的行為。
下面是圖解:
轉發
轉發的作用在伺服器端,將請求傳送給伺服器上的其他資源,以共同完成一次請求的處理。
使用forward跳轉時,是在伺服器內部跳轉,位址列不發生變化,屬於同一次請求。
使用方式
在要跳轉的地方使用getRequestDispatcher方法指定要跳轉的位置。
req.getRequestDispatcher("/url-pattern").forward(req,resp);
資料傳遞
forward表示一次請求,是在伺服器內部跳轉,可以共享同一次request作用域中的資料
request作用域:擁有儲存資料的空間,作用範圍是一次請求有效(一次請求可以經過多次轉發)。可以將資料存入request後,在一次請求過程中的任何位置進行獲取
可傳遞任何資料(基本資料型別、物件、陣列、集合等)存資料:request.setAttribute(key,value);
以鍵值對形式儲存在request作用域中。key為string型別,value為object型別取資料:requestgetAttribute(key);
通過string型別的key訪問object型別的value
例子:
建立兩個Servlet,AServlet
、BServlet
,在AServlet
BServlet
,再將資料取出。
package com.zjw; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/a") public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet doGet..."); //向request中存入資料 req.setAttribute("name","張三"); //請求轉發 跳轉到AServlet req.getRequestDispatcher("/b").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet doPost..."); doPost(req,resp); } }
package com.zjw;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/b")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doGet...");
//從request域中取資料
String name = (String) req.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doPost...");
doPost(req,resp);
}
}
通過瀏覽器訪問AServlet
,觀察瀏覽器的地址沒有發生變化
http://localhost:8080/servlet_war_exploded/a
控制檯輸出
AServlet doGet...
BServlet doGet...
張三
重定向
重定向作用在客戶端,客戶端將請求傳送給伺服器後,伺服器響應給客戶端一個新的請求地址,客戶端重新發送新請求。
使用方式
在呼叫業務邏輯的Servlet中,編寫以下程式碼
response.sendRedirect("目標URI");
- URl:統一資源識別符號(Uniform Resource ldentifier),用來表示伺服器中定位一個資源,資源在web專案中的路徑(/project/source)
例子:
建立兩個Servlet,AServlet
、BServlet
,在AServlet
新增一個數據,跳轉到BServlet
,再將資料取出。
package com.zjw;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/a")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doGet...");
//向request中存入資料
req.setAttribute("name","張三");
//重定向
resp.sendRedirect(req.getContextPath()+"/b");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doPost...");
doPost(req,resp);
}
}
package com.zjw;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/b")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doGet...");
//從request域中取資料
String name = (String) req.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doPost...");
doPost(req,resp);
}
}
通過瀏覽器訪問AServlet
,觀察瀏覽器的地址發生變化
//訪問
http://localhost:8080/servlet_war_exploded/a
//改變
http://localhost:8080/servlet_war_exploded/b
控制檯輸出,發現無法取得request域中的值。
AServlet doGet...
BServlet doGet...
null