两者区别
重定向:
- 地址栏会发生改变
- 数据会丢失(原有的request请求失效)
- 使用 response 进行重定向(response.sendRedirect("/path");)
- 重定向的过程在客户端+服务器端完成
请求转发:
- 地址栏不会发生改变
- 数据不会丢失(原有的request请求不会失效)
- 使用 request 进行请求转发(request.getRequestDispatcher("/path").forward(request, response);)
- 转发的过程在服务器内部完成(也是地址栏不改变的原因)
重定向
注意:所有的示例均使用@WebServlet() 注解来完成,不使用web.xml配置。
- 原Servlet类,在客户端访问该Servlet的地址
/**
* 原Servlet类,进行重定向。
*/
@WebServlet("/RedirectApp")
public class RedirectApp extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取request请求的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("重定向前: ");
System.out.println("\t username: " + username);
System.out.println("\t password: " + password);
// 此处进行重定向
response.sendRedirect("/JavaEE-01/RedirectTarget");
}
}
- 在源Servlet类中重定向到该目标Servlet
/**
* 重定向的目标源
*/
@WebServlet("/RedirectTarget")
public class RedirectTarget extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 先修改响应(response)的编码再获取 PrintWriter,客户端就不会有乱码
response.setCharacterEncoding("GBK");
PrintWriter writer = response.getWriter();
// 打印到浏览器端
writer.println("重定向后:");
writer.println("\t username: " + username);
writer.println("\t password: " + password);
}
}
- 测试结果
在浏览器地址栏访问: http://127.0.0.1:8080/JavaEE-01/RedirectApp?username=123&password=aaa
控制台显示:
再看浏览器端:
由此可看出在重定向前是可以获取到数据的,重定向后浏览器的地址栏发生了变化,并且获取不到数据,原因是重定向后的request已经不是原来的request, 而是新的request
请求转发
- 原Servlet类
@WebServlet("/RequestDispatcherApp")
public class RequestDispatcherApp extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 在控制台打印
System.out.println("请求转发前: ");
System.out.println("\t username: " + username);
System.out.println("\t password: " + password);
// 转发时将request, response 请求带过去,request请求中的数据不会丢失
request.getRequestDispatcher("/RequestDispatcherTarget").forward(request, response);
}
}
- 请求转发的目标Servlet类
@WebServlet("/RequestDispatcherTarget")
public class RequestDispatcherTarget extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
response.setCharacterEncoding("GBK");
PrintWriter writer = response.getWriter();
// 在浏览器端打印
writer.println("请求转发后:");
writer.println("\t username: " + username);
writer.println("\t password: " + password);
}
}
- 测试结果
在浏览器地址栏访问: 127.0.0.1:8080/JavaEE-01/RequestDispatcherApp?username=123&password=aaa
控制台显示:
浏览器端显示:
由测试结果可看出,请求转发后的数据并没有丢失,浏览器的地址栏也并没有发生改变;