转发:是服务端的行为,重定向:是客户端的行为
转发过程:
客户端首先发送一个请求到服务器,服务器匹配Servlet,并指定执行。当这个Servlet执行完后,它要调用getRequestDispacther()方法,把请求转发给指定的testservlet,整个流程都是在服务端完成的,而且是在同一个请求里面完成的,因此Servlet和testservlet共享同一个request,在ForwardServlet里面放的所有东西,在testservlet中都能取出来。因此,testservlet能把结果getAttribute()出来,getAttribute()出来后执行完把结果返回给客户端,整个过程是一个请求,一个响应。
重定向过程:
客户端发送一个请求到服务器端,服务器匹配Servlet,这都和请求转发一样。Servlet处理完之后调用了sendRedirect()这个方法,这个方法是response方法。所以,当这个Servlet处理完后,看到response.sendRedirect()方法,立即向客户端返回个响应,响应行告诉客户端你必须再重新发送一个请求,去访问testservlet,紧接着客户端收到这个请求后,立刻发出一个新的请求,去请求testservlet,在这两个请求互不干扰、相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。因此,在sendRedirect()里面是两个请求,两个响应。
Forward是在服务器端的跳转,就是客户端一个请求给服务器,服务器直接将请求相关参数的信息原封不动的传递到该服务器的其他jsp或Servlet去处理。而sendRedirect()是客户端的跳转,服务器会返回客户端一个响应报头和新的URL地址,原来的参数信息如果服务器没有特殊处理就不存在了,浏览器会访问新的URL所指向的Servlet或jsp,这可能不是原来服务器上的webService了。
重定向和转发的区别
1、转发是在服务器端完成的,重定向是在客户端发生的;
2、转发是同一次请求,重定向是两次请求;
3、转发地址栏没有变化,重定向地址栏有变化;
4、转发只能在同一个WEB项目范围内进行,重定向可以再同一个WEB项目内,也可以重定向到其他任意地方;
eg:response.sendRedirect("https://www.baidu.com");
1. RedirectServlet 类(执行重定向到 testServlet类)
package com.java12.javaweb.demo.redirect;
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("/redirect")
public class RedirectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public RedirectServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("RedirectServlet......doGet");
request.setAttribute("name", "zdm");
System.out.println("RedirectServlet's name: " + request.getAttribute("name"));
//执行请求的重定向, 直接调用 response.sendRedirect(path) 方法,
//path 为要重定向的地址
String path = "testServlet";
response.sendRedirect(path);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2.testservlet (重定向到的servlet)
package com.java12.javaweb.demo.redirect;
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("/testServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public TestServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("TestServlet doGet方法");
Object ab= request.getAttribute("name");
System.out.println("TestServlet is"+ab);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.ForwardServlet转发
package com.java12.javaweb.demo.redirect;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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("/forward")
public class ForwardServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ForwardServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ForwardServlet's doGet");
request.setAttribute("name", "liujie");
System.out.println("ForwardServlet's name: " + request.getAttribute("name"));
//请求的转发.
//1. 调用 HttpServletRequest 的 getRequestDispatcher() 方法获取 RequestDispatcher 对象
//调用 getRequestDispatcher() 需要传入要转发的地址
String path = "testServlet";
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/" + path);
//2. 调用 HttpServletRequest 的 forward(request, response) 进行请求的转发.
requestDispatcher.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
注意:@WebServlet用注解来实现servlet和url的映射,但是名字不能相同,如果相同会报错,如下所示:
转发和重定向的选择
1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,所以如果在使用转发和重定向都无所谓的时候建议使用转发。
2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。