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

news2024/11/26 2:30:34

文章目录

  • 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()的区别

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/167445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系分 - 案例分析 - 系统设计

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 系统设计结构化设计SD内聚偶然内聚逻辑内聚时间&#xff08;瞬时&#xff09;内聚过程内聚通信内聚顺序内聚功能内聚耦合内容耦合公共耦合外部耦合控制耦合标记耦合数据耦合非直接耦合补…

DTO 与 PO的相互转换

目录 常见Bean映射框架 Dozer Orika MapStruct ModelMapper JMapper 测试模型 转化器 OrikaConverter DozerConverter MapperStructConvert JMapperConvert ModelMapperConverter 测试 平均时间 吞吐量 SingleShotTime 采集时间 DTO&#xff08;Data Transfer …

Android项目Gadle统一依赖管理

一.Gradle管理依赖版本 在中大型Android项目中&#xff0c;都会有多个Module进行协同配合。这些module中可能会依赖同一个库的不同版本&#xff0c;这将导致一些问题&#xff0c;要么是代码冲突&#xff0c;要么是APK包体积增大&#xff0c;亦或是项目构建的时间变长&#xff…

在Revit里如何将普通墙与曲面墙的内壁连接

在Revit里如何将普通墙与曲面墙的内壁连接&#xff1f;创建异形建筑时&#xff0c;为了达到如图1所示的效果&#xff0c;该如何操作&#xff1b; 我们可以使用体量建模的方式来创建该类建筑&#xff0c;要点在于如将幕墙与曲面墙的内壁连接。具体方法如下&#xff1a; 一、创建…

ASP.NET Core+Element+SQL Server开发校园图书管理系统(一)

随着技术的进步&#xff0c;跨平台开发已经成为了标配&#xff0c;在此大背景下&#xff0c;ASP.NET Core也应运而生。本文主要基于ASP.NET CoreElementSql Server开发一个校园图书管理系统为例&#xff0c;简述基于MVC三层架构开发的常见知识点&#xff0c;仅供学习分享使用&a…

ubuntu20.04下出现protoc与gazebo版本问题

ubuntu20protocgazebo问题描述问题定位解决方案问题描述 今天在搞路径规划算法时&#xff0c;从git上拉下来一个算法&#xff0c;ros环境那些都有&#xff0c;但是在编译的时候出现了如下图所示的一下问题&#xff1a;&#xff08;为了方便搜索关键词&#xff09; In file incl…

锂离子电池热失控预警资料整理(三)

此前 个人搜集了一些锂电池热失控预警相关期刊、文献&#xff0c;并整理了一些个人认为重要的逻辑、知识点&#xff0c;希望通过此分享让有需要的人了解一些内容&#xff0c;如有问题欢迎同我探讨~ 锂离子电池热失控预警资料整理&#xff08;三&#xff09;九、基于数据分析的锂…

C语言基于FOC控制算法和STM32主控芯片的双路直流无刷电机控制器源码

【FOCSTM32】双路直流无刷电机矢量控制器-使用文档 &#x1f4d5; 介绍 控制器主控芯片采用STM32F405RGT6&#xff0c;控制器底层基于HAL库和FreeRTOS实时操作系统&#xff0c;预留CAN、USART、SWD、USB接口各一&#xff0c;便于通信和控制的工程应用。该控制器提供双路无刷电…

2022年艺术品和古董投资策略研究报告

第一章 行业概况 艺术品是艺术家智力劳动成果的结晶。作为一种特殊商品流通于艺术市场&#xff0c;与其他商品相同的是&#xff0c;它也具备普通商品的基本属性&#xff1a;使用价值和价值。不同的是&#xff0c;艺术品的使用价值体现在精神层面而不是物质层面上&#xff0c;它…

RabbitMQ消息队列实战(1)—— RabbitMQ的体系

RabbitMQ是一个开源的消息代理和队列服务器&#xff0c;用来在不同的应用之间共享数据。1983年&#xff0c;被认为是RabbitMQ的雏形的Teknekron创建&#xff0c;首次提出了消息总线的概念。中间经历过数个阶段的发展&#xff0c;一直到2004年&#xff0c;AMQP&#xff08;Advan…

02.指针的进阶

1.字符指针 在指针的类型中我们知道有一种指针类型为字符指针 char* ; 一般使用: int main() {char ch w;char *pc &ch;*pc w;return 0; } char * p---const char * p(因为常量字符串不能被修改) #include<stdio.h> int main() {const char * pstr "hel…

从汇编的角度了解C++原理——虚函数

文章目录1、虚函数1.1、虚函数储存结构1.2、子类重写虚函数1.3、在栈上调用虚函数1.4、在堆上调用虚函数(通过指针调用&#xff0c;多态)本文用到的反汇编工具是objconv&#xff0c;使用方法可以看我另一篇文章https://blog.csdn.net/weixin_45001971/article/details/12866064…

编译基于armV8架构的opencv,并在rock3a开发板上运行

近期在基于arm开发板做图像识别任务开发时&#xff0c;需要用到Opencv库 之前在做rknpu开发时&#xff0c;开发sdk里面已经集成了opencv 但是该opencv开发包不能实现imshow/VideoCapture等函数&#xff0c;经过调研&#xff0c;决定对opencv源代码进行编译&#xff0c;生成arm…

安科瑞能耗监测系统在新疆昌吉市政务中心项目的研究与应用

安科瑞 华楠摘要&#xff1a;大型公共建筑总面积不足城镇建筑总面积的4%&#xff0c;但总能耗却占全国城镇总耗电量的22%&#xff0c;大型公共建筑单位面积年耗电量达到70&#xff5e;300KWh&#xff0c;为普通居民住宅的10&#xff5e;20倍。公共建筑是节能大户和节能核心&…

Delphi 11.2 安装 CnWizards 组件包

官方网址&#xff1a;https://www.cnpack.org/showdetail.php?id900&langzh-cn 开源免费的组件包&#xff0c;大大提高了开发效率&#xff0c;再次感谢大佬们的无私奉献 这个组件包主要是为了实现一些delphi没有的便捷设置&#xff0c;以及能给delphi增加了一些好用的辅助…

惊艳的产品背后,是锐利的设计思维

缘起 几年前&#xff0c;我偶然用一个 叫 Zine 的小app 写了两篇文章&#xff0c;感觉非常好。 后来在网上认识 了Zine 团队的创始人 Louis&#xff0c;也喜欢上了他们的另一个 App&#xff1a;Varlens&#xff0c; 最近他们推出了记笔记的 App Lattics&#xff0c;一些功能也…

《 Unity Shader 入门精要》 第3章 Unity Shader 基础

第3章 Unity Shader 基础 3.1 Unity Shader 概述 材质与 Unity Shader 在 Unity 中我们通常需要将材质&#xff08;Material&#xff09; 和 Unity Shader 配合使用&#xff0c;常见流程如下&#xff1a; 创建一个材质创建一个 Unity Shader&#xff0c; 并将它赋给材质将材…

Android View类

布局定义了应用中的界面结构&#xff08;例如 Activity 的界面结构&#xff09;。布局中的所有元素均使用 View 和 ViewGroup 对象的层次结构进行构建。View 通常用于绘制用户可看到并与之交互的内容。ViewGroup 则是不可见的容器&#xff0c;用于定义 View 和其他 ViewGroup 对…

AppScan自定义扫描策略,扫描针对性漏洞

系列文章 AppScan介绍和安装 AppScan 扫描web应用程序 AppScan被动手动探索扫描 AppScan绕过登录验证码深入扫描 第五节-AppScan自定义扫描策略&#xff0c;扫描针对性漏洞 AppScan安全扫描往往速度是很慢的&#xff0c;有些场景下他的扫描项目又不是我们需要的&#xff0c;…

如何实现六轴机械臂的逆解计算?

1. 机械臂运动学介绍 机械臂运动学 机器人运动学就是根据末端执行器与所选参考坐标系之间的几何关系&#xff0c;确定末端执行器的空间位置和姿态与各关节变量之间的数学关系。包括正运动学&#xff08;Forward Kinematics&#xff09;和逆运动学&#xff08;Inverse Kinemati…