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

请求转发:

请求转发,即request.getRequestDispatcher().forward(),是一种服务器的行为,客户端只有一次请求,服务器端转发后会将请求对象保存,地址栏中的URL地址不会改变,得到响应后服务器端再将响应发给客户端;

请求重定向:

请求重定向,即response.sendRedirect(),是一种客户端行文,从本质上讲等同于两次请求,前一次请求对象不会保存,地址栏的URL地址会改变。


用生活中一个常见的例子来说明两者之间的区别,某人要去办理护照:

转发:某人去了甲局,甲局看了之后,直到护照应该由乙局来管,但甲局的工作人员并没有赶走某人,而是让某人等着,自己在办公室后面联系了乙局的工作人员,乙局护照办好后送到了甲局,然后甲局的工作人员将护照交给了某人;

重定向:某人去了甲局后,甲局的工作人员说护照不归他们关,应该去乙局。然后某人自己去了乙局,办了护照。


这里写一个例子演示两者的不同。新建一个web项目,创建三个页面:reg.jsp、response.jsp、request.jsp。

reg.jsp代码如下:

  <body><h1>你好</h1><hr><form name="regForm" action="response.jsp" method="post"><table><tr><td>用户名:</td><td><input type="text" name="username"/></td></tr><tr><td colspan="2"><input type="submit" value="提交"/></td></tr></table></form></body>
这里输入用户名,然后交给response.jsp处理。页面如下:


response.jsp代码如下:

<%response.setContentType("text/html;charset=utf-8");out.println("<h1>response内置对象</h1>");out.println("<hr>");response.sendRedirect("request.jsp");//request.getRequestDispatcher("request.jsp").forward(request, response);
%>
首先,使用重定向交给request.jsp来处理。

response.jsp代码如下:

<body><h1>request对象</h1><hr>你是谁?<%=request.getParameter("username") %></body>
这里仅仅获得用户名进行输出。

使用重定向时,结果如下:

可以看到,输入的用户名没有显示出来,这是因为重定向本质上相当于两次请求,而前一次请求不保存,所以没能得到用户名。同时,可以看到地址栏中的URL地址由response.jsp变为了request.jsp。

第二次,修改response.jsp的代码如下:

<%response.setContentType("text/html;charset=utf-8");out.println("<h1>response内置对象</h1>");out.println("<hr>");//response.sendRedirect("request.jsp");request.getRequestDispatcher("request.jsp").forward(request, response);
%>
使用转发,将请求转发给request.jsp来处理,结果如下:


可以看到,页面得到了请求中的用户名并进行显示,这是由于转发时客户端只有一次请求,服务器会保存这次请求,等到转发返回时将结果返回给客户端。同时,页面显示的是request.jsp的内容,但地址栏中的URL地址并没有变化。


这就是请求转发与请求重定向的区别。

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

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

相关文章

StringBuilder详解

1、简介 StringBuilder和StringBuffer一样&#xff0c;都是继承自抽象类AbstractStringBuilder类&#xff0c;也是一个可变的字符序列。StringBuilder和StringBuffer非常相似&#xff0c;甚至有互相兼容的API&#xff0c;不过&#xff0c;StringBuilder不是线程安全的&#xf…

【线程】互斥锁

一、互斥锁 1. 函数原型 pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); pthread_mutex_destroy(pthread_mutex_t *mutex); 分析&#xff1a; pthread_mutex_t 类型&#xff0c;其本质是一个结构体&#xff0c;为简化…

ArrayList详解

1、简介 ArrayList是Java集合框架中的一个重要的类&#xff0c;它继承于AbstractList&#xff0c;实现了List接口&#xff0c;是一个长度可变的集合&#xff0c;提供了增删改查的功能。集合中允许null的存在。ArrayList类还是实现了RandomAccess接口&#xff0c;可以对元素进行…

【进程】进程组

一、进程组 1. 进程组 &#xff08;1&#xff09;进程组&#xff0c;也称之为作业&#xff0c;BSD与1980年前后向UNIX中增加的一个新特性&#xff0c;代表一个或多个进程的集合。每个进程都属于一个进程组&#xff0c;在waitpid函数和kill函数的参数中都曾经使用到&#xff0c…

函数wait、waitpid、孤儿进程、僵尸进程

一、函数wait、waitpid 一个进程在终止时会关闭所有文件描述符&#xff0c;释放在用户空间释放的内存&#xff0c;但它的PCB还保留着&#xff0c;内核在其中保存一些信息&#xff1a;如果是正常终止时则保存着退出状态&#xff0c;如果是异常终止则保存着导致该进程终止的信号是…

MySQL中的字符集与字符序

这篇文章详细介绍一下MySQL中的字符集和字符序相关的问题&#xff0c;里里外外地了解一下字符集和字符序的方方面面&#xff0c;同时重点说明一下开发中需要注意的问题。 文章基于MySQL 8.0&#xff0c;也会涉及到5.7版本。主要参考MySQL手册&#xff1a;https://dev.mysql.com…

【C++ Primer | 15】虚函数表剖析(一)

一、虚函数 1. 概念 多态指当不同的对象收到相同的消息时&#xff0c;产生不同的动作 编译时多态&#xff08;静态绑定&#xff09;&#xff0c;函数重载&#xff0c;运算符重载&#xff0c;模板。运行时多态&#xff08;动态绑定&#xff09;&#xff0c;虚函数机制。为了实现…

Leetcode 118. 杨辉三角

给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例: 输入: 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ] class Solution { public:vector<vector<int>> generate(…

Linux本地yum源配置以及使用yum源安装各种应用程序

将软件包传送到Linux中后&#xff0c;挂载&#xff0c;然后配置yum软件仓库&#xff0c;最后就可以使用yum来安装相应的应用程序了。假设挂载目录为/tmp/ruanjianbao&#xff0c;则下面说明配置本地yum仓库的过程&#xff1a; &#xff08;1&#xff09;cd /etc/yum.repos.d/…

【第15章】多重继承

1. 虚基类介绍 多继承时很容易产生命名冲突&#xff0c;即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字&#xff0c;命名冲突依然有可能发生&#xff0c;比如非常经典的菱形继承层次。如下图所示&#xff1a; 类A派生出类B和类C&#xff0c;类D继承自类B和…

1. 排序算法

一、概述 假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#xff0c;这些记录的相对次序保持不变&#xff0c;即在原序列中&#xff0c;r[i]r[j]&#xff0c;且r[i]在r[j]之前&#xff0c;而在排序后的序列中&#xff0c;r[i]仍…

【C++ Priemr | 15】构造函数与拷贝控制

继承的构造函数 1. 简介&#xff1a; 子类为完成基类初始化&#xff0c;在C11之前&#xff0c;需要在初始化列表调用基类的构造函数&#xff0c;从而完成构造函数的传递。如果基类拥有多个构造函数&#xff0c;那么子类也需要实现多个与基类构造函数对应的构造函数。 class …

【C++ Priemr | 15】面向对象程序设计

类型准换与继承 为了支持c的多态性&#xff0c;才用了动态绑定和静态绑定。 需要理解四个名词&#xff1a; 对象的静态类型&#xff1a;对象在声明时采用的类型&#xff0c;是在编译期确定的。对象的动态类型&#xff1a;目前所指对象的类型&#xff0c;是在运行期决定的。对…

【C++ Priemr | 15】虚函数表剖析(三)

一、虚拟菱形继承 #include <iostream> using namespace std;class B { public:int _b; };class C1 :virtual public B { public:int _c1; };class C2 :virtual public B { public:int _c2; };class D :public C1, public C2 { public:int _d; };int main() {cout <&…

程序的装入和链接

注&#xff1a;这是本人学习汤小丹等编写的计算机操作系统&#xff08;西安电子科技大学出版社&#xff09;的学习笔记&#xff0c;因此许多引用来源于此书&#xff0c;在正文中就不注明了&#xff01; 程序在运行前需要经过以下步骤&#xff1a;编译程序对源程序进行编译生成…

静态库的制作和使用

Linux下的静态库为lib*.a格式的二进制文件&#xff08;目标文件&#xff09;&#xff0c;对应于Windows下的.lib格式的文件。 &#xff08;1&#xff09;命名规则 lib库名字 .a libMytest.a &#xff0c;则库名字为mytest。下面以具体的代码为例介绍如何制作静态库。 //mai…

虚拟地址空间

对于每一个进程都会对应一个虚拟地址空间&#xff0c;对于32位的操作系统&#xff08;其指令的位数最大为32位&#xff0c;因此地址码最多32位&#xff09;&#xff0c;虚拟地址空间的大小为B即0~4GB的虚拟地址空间&#xff0c;其中内核空间为1GB&#xff0c;如下所示&#xff…

动态库(共享库)的制作和使用

Linux下的动态库为lib*.so格式的二进制文件&#xff08;目标文件&#xff09;&#xff0c;对应于Windows下的.dll格式的文件。 &#xff08;1&#xff09;命名规则 lib库名.so &#xff08;2&#xff09;动态库的制作 1&#xff09;生成与位置无关的代码&#xff08;.o&…

网络编程套接字API

uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);int inet_pton(int family, const char *strptr, void *addrptr); 分析&#xff1a; 第一个参数可以是AF_INET或AF_INET6&am…

gdb调试器(三)

File/file 装入想要调试的可执行文件 run(r) 执行当前被调试的程序 kill(k) 终止正在调试的程序 quit(q) 退出gdb shell 使用户不离开gdb就可以执行Linux的shell命令 backtrace(bt) 回溯跟踪&#xff08;当对代码进行调试时&#xff0c;run后…