目录
一、转发(forward)
1. 实现步骤
2. 图解
3. 代码示例
1. 请求转发
2. 共享数据
3. 结果
4. 转发的特点
二、重定向(redirect)
1. 实现步骤
1. 设置状态码为302
2. 设置响应头
注. 一种简单的重定向方法
2. 图解
3. 代码示例
1. 编写ResponseDemo1,将请求重定向到ResponseDemo2。
2. 编写ResponseDemo2,直接输出信息。
3. 结果
4. 重定向的特点
三、转发和重定向的区别(总结)
一种在服务器内部的资源跳转方式。
request.getRequestDispatcher("/RequestDemo6").forward(request,response);
注意这里是给服务器用,所以不需要获取虚拟目录,即 request.getContextPath();
客户端浏览器发送请求到RequestDemo5,RequestDemo5转发请求到RequestDemo6,并且共享request域对象“Ray”。
设置一个数据域,并且把它转发到RequestDemo6。
@WebServlet(name = "RequestDemo5", value = "/RequestDemo5")
public class 请求转发 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name","Ray");
request.getRequestDispatcher("/RequestDemo6").forward(request,response); //给服务器用,路径不需要加虚拟目录
System.out.println("RequestDemo5被访问了。");
}
}
获取RequestDemo5中的数据域,并打印信息。
@WebServlet(name = "RequestDemo6", value = "/RequestDemo6")
public class 共享数据 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object name = request.getAttribute("name");
System.out.println(name);
System.out.println("RequestDemo6被访问了。");
}
}
当我们再浏览器下输入localhost:8080/Web/RequestDemo5并敲击回车后,可以看到:
1. 抓包分析后,发现虽然访问到了2个servlet,但是实际上却是一次请求。
2. 当我们把要转发到的资源 /RequestDemo6 换成 www.baidu.com 发现并不能实现转发(404 not found),说明了只能转发到当前服务器内部资源中。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name","Ray");
request.getRequestDispatcher("www.baidu.com").forward(request,response); //给服务器用,路径不需要加虚拟目录
System.out.println("RequestDemo5被访问了。");
}
3. 浏览器地址栏路径不发生变化
另一种资源跳转的方式。
response.setStatus(302);
response.setHeader("location","/Web/responseServletDemo2");
response.sendRedirect(contextPath + "/responseServletDemo2");
@WebServlet(name = "responseServletDemo1", value = "/responseServletDemo1")
public class 重定向 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Demo1!!!");
// response.setStatus(302); //设置状态码为302(重定向)
// response.setHeader("location","/Web/responseServletDemo2"); // 设置响应头location
String contextPath = request.getContextPath(); //动态获取虚拟目录
//简单重定向方法
response.sendRedirect(contextPath + "/responseServletDemo2"); //给客户端用,需要加虚拟目录
}
}
注意:这里给客户端使用,需要加虚拟目录。即 request.getContextPath();
@WebServlet(name = "responseServletDemo2", value = "/responseServletDemo2")
public class 重定向Demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Demo2!!!!");
}
}
当我们输入localhost:8080/Web/responseServletDemo1 敲击回车发现浏览器地址会瞬间变成
localhost:8080/Web/responseServletDemo2 ,抓包分析发现浏览器一共发送了2次请求。
回到输出窗口,发现ResponseDemo1和ResponseDemo2的信息都被输出了。
- 转发的地址栏不变,而重定向变成转发后的资源。
- 转发是一次请求,而重定向是两次请求。所以一般可以说重定向是2次转发。
- 转发只能在自己内部服务器资源内相互转发,而重定向可以访问其他站点。