当前位置: 首页 > news >正文

getRequestDispatcher()转发和sendRedirect()重定向介绍与比较

文章目录

  • 1. request.getRequestDispatcher()
    • 1.1请求转发和请求包含的区别
    • 1.2request域
  • 2.response.sendRedirect()
  • 3.请求转发与重定向的区别
    • 比较测试

1. request.getRequestDispatcher()

getRequestDispatcher()包含两个重要方法,分别是请求转发和请求包含。一个请求跨多个Servlet时,需要使用请求转发和请求包含。

首先需要获得一个RequestDispatcher 对象:
RequestDispatcher rd = request.getRequestDispatcher("/MyServlet");
然后

  • 请求转发: rd.forward( request , response );
  • 请求包含: rd.include( request , response);
    在这里插入图片描述
    需注意的是,无论是请求转发还是请求包含,都在一个请求范围内!使用同一个request和response!

1.1请求转发和请求包含的区别

  • 请求转发:由下一个Servlet完成响应体,当前Servlet可以设置响应头(留头不留体)。
    举个例子,AServlet请求转发到BServlet,那么AServlet不能够使用response.getWriter() 和response.getOutputStream()向客户端输出响应体,但可以使用response.setContentType(“text/html;charset=utf-8”) 设置响应头。而在BServlet中可以输出响应体。
  • 请求包含:由两个Servlet共同完成响应体(留头又留体)。同样用上面的例子,AServlet请求包含到BServlet,那么AServlet既可以设置响应头,也可以完成响应体。

下图是请求转发的流程,最后返给客户端的response只是BServlet的,而AServlet的响应不会在客户端显示出来。
在这里插入图片描述
下图是请求包含流程,因为BServelt的响应返回给AServlet时携带了responseB,所以AServlet的响应中包含了BServlet的响应,最后返给客户端的响应是两者之和。
在这里插入图片描述

1.2request域

request是Java四大域对象之一,正是它提供了请求转发和请求包含的功能。一个请求会创建一个request对象,若在一个请求中跨越了多个Servlet,那么这些Servlet可以使用request来共享数据。同一个请求范围内使用request.setAttribute()和request.getAttribute()来传值!前一个Servlet调用setAttribute()保存值,后一个Servlet调用getAttribute()获取值

2.response.sendRedirect()

response和request一样都是jsp内置对象,request是获取用户的请求,response处理用户请求。sendRedirect()函数的作用是重定向网页,向浏览器发送一个特殊的Header,然后由浏览器来做重定向,转到指定的页面。下面创建四个页面,首先是sex.jsp,有一个下拉列表和提交按钮确定,选择“男”,就跳转到male.jsp,选择“女”就跳转到female.jsp,中间通过sex_action.jsp进行重定向

<!-- sex.jsp -->
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>Sex Select's page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
    <form action="<%=basePath%>c03/sex_action.jsp" method="post">
        <select name="sex">
            <option></option>
            <option></option>
        </select>
        <button type="submit">提交</button>
    </form>
</body>
</html>
<!-- sex_action.jsp -->
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'sex_action.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
    <% 
        request.setCharacterEncoding("UTF-8");
        String sex = request.getParameter("sex");
        out.println(sex);
        if("男".equals(sex)) {
            response.sendRedirect("male.jsp");
            return;
        }
        else if("女".equals(sex)) {
            response.sendRedirect("female.jsp");
            return;
        }
    %>
</body>
</html>

3.请求转发与重定向的区别

  1. 请求转发是一个请求一次响应,而重定向是两次请求两次响应。
  2. 请求转发地址不变化,而重定向会显示后一个请求的地址。这是因为请求转发服务器的行为,是由容器控制的转向,整个过程处于同一个请求中,因此客户端浏览器不会显示转向后的地址;但重定向客户端的行为,重新发送了请求,整个过程不在同一个请求中,因此客户端浏览器会显示跳转后的地址。
  3. 请求转发只能转发到本项目其它Servlet,而重定向不只能重定向到本项目的其它Servlet,还能定向到其它项目。
  4. 请求转发是服务端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,既包含项目名
  5. request.getRequestDispatcher()是请求转发,前后页面共享一个request,返回的是一个RequestDispatcher对象, response.sendRedirect()是重新定向,前后页面不是一个request,
  6. RequestDispatcher.forward()是在服务器端运行,HttpServletResponse.sendRedirect()是通过向客户浏览器发送命令来完成,所以RequestDispatcher.forward()对于浏览器来说是“透明的”,而HttpServletResponse.sendRedirect()则不是
  7. ServletContext.getRequestDispatcher(String url)中的url只能使用绝对路径; 而ServletRequest.getRequestDispatcher(String url)中的url可以使用相对路径。因为ServletRequest具有相对路径的概念;而ServletContext对象无次概念。

请求转发示意图
在这里插入图片描述
重定向示意图
在这里插入图片描述

比较测试

环境准备:
login.jsp 所在目录: /webapp/ jsp/ login.jsp
servelt /GoHallCI
工程名字: /MyShopping

实际测试:

1、req.getRequestDispatcher(“jsp/login.jsp”).forward(req, resp); 测试结果: 可转发,实际访问地址:http://localhost:8080/MyShopping/GoHallCI?type=login
1、req.getRequestDispatcher(“/jsp/login.jsp”).forward(req, resp); 测试结果:可转发 实际访问地址:http://localhost:8080/MyShopping/GoHallCI?type=login
1、req.getRequestDispatcher(“/login.jsp”).forward(req, resp); 测试结果:不可转发 实际访问地址,找不到
1、req.getRequestDispatcher(“login.jsp”).forward(req, resp); 测试结果:不可转发 实际访问地址 ,找不到
1、req.getRequestDispatcher(req.getContextPath()+“login.jsp”).forward(req, resp); 实际访问地址,找不到 [/MyShoppinglogin.jsp] 未找到
1、req.getRequestDispatcher(req.getContextPath()+“/login.jsp”).forward(req, resp); 实际访问地址,找不到 [/MyShopping/login.jsp] 未找到
1、req.getRequestDispatcher(req.getContextPath()+“jsp/login.jsp”).forward(req, resp); 实际访问地址,找不到 [/MyShoppingjsp/login.jsp] 未找到
1、req.getRequestDispatcher(req.getContextPath()+“/jsp/login.jsp”).forward(req, resp); 实际访问地址,找不到 [/MyShopping/jsp/login.jsp] 未找到
1、req.getRequestDispatcher(req.getContextPath()+“/GoHallCI”).forward(req, resp); 实际访问地址,[找不到 http://localhost:8080/MyShopping/GoHallCI?type=login]
1、req.getRequestDispatcher(“/MyShopping/jsp/login.jsp”).forward(req, resp); 实际访问地址,找不到 文.件[/MyShopping/jsp/login.jsp] 未找到
1、req.getRequestDispatcher(“/GoHallCI”).forward(req, resp); 实际访问地址 http://localhost:8080/MyShopping/GoHallCI?type=login
req.getRequestDispatcher()后面如果还有语句,那么在转发页面,后台仍然会执行对应语句,直到语句执行结束!
2、在jsp里面 <a href=“${pageContext.request.contextPath}/jsp/login.jsp” .>登录</a.> , 实际访问地址:http://localhost:8080/MyShopping/jsp/login.jsp
3、resp.sendRedirect(req.getContextPath()+“/hall”); 测试结果 : 可重定向 实际重定向地址:http://localhost:8080/MyShopping/hall
3、resp.sendRedirect(“jsp/login.jsp”); 测试结果: 可重定向,实际访问地址:http://localhost:8080/MyShopping/jsp/login.jsp**
3、resp.sendRedirect(“/jsp/login.jsp”); 测试结果:不可重定向 实际访问地址:http://localhost:8080/jsp/login.jsp
3、resp.sendRedirect(“/login.jsp”); 测试结果:不可重定向 实际访问地址,http://localhost:8080/login.jsp
3、resp.sendRedirect(“login.jsp”); 测试结果:不可重定向 实际访问地址 ,http://localhost:8080/MyShopping/login.jsp
3、resp.sendRedirect(req.getContextPath()+“login.jsp”); 测试结果:不可重定向 实际访问地址,http://localhost:8080/MyShoppinglogin.jsp
3、resp.sendRedirect(req.getContextPath()+“/login.jsp”); 测试结果:不可重定向 实际访问地址,http://localhost:8080/MyShopping/login.jsp
3、resp.sendRedirect(req.getContextPath()+“jsp/login.jsp”); 测试结果:不可重定向 实际访问地址,http://localhost:8080/MyShoppingjsp/login.jsp
3、resp.sendRedirect(req.getContextPath()+“/jsp/login.jsp”); 测试结果:可重定向 实际访问地址 http://localhost:8080/MyShopping/jsp/login.jsp
3、resp.sendRedirect(req.getContextPath()+“/GoHallCI”); 测试结果 :可重定向 实际访问地址,http://localhost:8080/MyShopping/GoHallCI
3、resp.sendRedirect(“/MyShopping/jsp/login.jsp”); 测试结果:可重定向 实际访问地址,http://localhost:8080/MyShopping/jsp/login.jsp
3、resp.sendRedirect(“/GoHallCI”); 测试结果:不可重定向 实际访问地址 http://localhost:8080/GoHallCI

小结:
req.getRequestDispatcher() 的url 只能使用 jsp/login.jsp的相对路径或者/jsp/login.jps的绝对路径访问,支持填写servlet
resp.sendRedirect() 除了支持 jsp/login.jsp的相对路径,还支持自己拼接全路径 req.getContextPath()+"/jsp/login.jsp,也可以自己直接写全,/MyShopping/jsp/login.jsp

参考博文(侵删):
关于request.getRequestDispatcher()的两个方法以及request域
细谈getRequestDispatcher()与sendRedirect()的区别

getRequestDispatcher()与sendRedirect()的区别

相关文章:

  • wordpress开放多站点/武汉谷歌seo
  • 网站访客qq获取/如何投放网络广告
  • wordpress前端验证/音乐接单推广app平台
  • 北京网站建设服务/电子商务培训
  • 2017做那个网站能致富/如何优化网站首页
  • 二级域名能查到一级域名吗/湖南seo网站开发
  • FLStudio水果21最新Daw (宿主软件)电音混音编曲制作工具
  • 消息中间件简介
  • JavaWeb基础(一) Mybatis使用详解
  • 带你从概念到服务对象,解读商业智能BI
  • UE4 反射 学习笔记
  • c语言小练pintia11-20
  • 小程序容器技术助力突破智能汽车瓶颈
  • 【Lp-CVT and Applications】
  • rancher的k3s证书过期
  • Java使用流去除集合中某个字段为空的对象
  • win10+ubuntu23.04双系统安装
  • 数据分析-深度学习Pytorch Day6