重定向和转发(转)

2024-08-24 05:18
文章标签 转发 重定向

本文主要是介绍重定向和转发(转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说起重定向,转发,每个Web开发者估计都能头头是道的说上几句类似于重定向会显示真实路径,转发不会以及其它一类教科书式的概念。这些概念也都没错,但却没从本质上说明这两者的区别。更别提其根本原理是怎么实现的,以及为何重定向之后,原来的request中的数据都丢掉了,而转发却还是能保证request中的数据依然保留呢?

作为一个有追求的程序员,希望本文可以让你深入了解这两者的本质区别,从而知其所以然。

定义

首先来看两者的javadoc。

sendRedirect()
/**
* Sends a temporary redirect response to the client using the 
specified redirect location URL. This method can accept relative URLs; the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading '/' the container interprets it as relative to the current request URI.
If the location is relative with a leading '/' the container interprets it as relative to the servlet container root.
*/
public void sendRedirect(String location) throws IOException;

重定向是向客户端发送一个指定URL的临时重定向的响应。

forward()
/**
* Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response.
The request and response parameters must be either the same objects as were passed to the calling servlet's service method .
*/
public void forward(ServletRequest request, ServletResponse response);

转发,则是将一个请求转到服务器的另一个资源。在处理完初步请求另外的资源之后生成响应。

定义基本说明了转发操作为何可以保持request内的parameter,attribute这些值都可以保留,而重定向操作却会丢弃的原因:

转发是在服务端完成的,并没有经过客户端
转发整个操作完成后才生成响应
重定向是服务端向客户端发送指定的URL
重定向是在客户端完成的

我们再来看Tomcat内部,对于两者是怎样一种实现方式。

  1. 容器实现

我们在servlet内部一般对于这两者的使用形式也相当直观,例如对于hello.jsp的请求:

sendRedirct方法
response.sendRedirect("/hello.jsp");

此时,内部的处理方式如下:

public void sendRedirect(String location, int status) throws IOException {
// Generate a temporary redirect to the specified location
try {String absolute = toAbsolute(location);setStatus(status); //这里,重定向是返回302状态码以及Location和对应的url
setHeader("Location", absolute);} catch (IllegalArgumentException e) {setStatus(SC_NOT_FOUND);}}

展现在浏览器中的结果如下:

即根据Location,浏览器最终再发起新的请求,最终展现在浏览器中的即为新请求的URL,也就是大家常说的重定向会显示最终的URL。

有上这些并不能造成重定向操作将之前request中已经绑定的一系列parameter和attribute丢掉。最根本的原因是一个请求完整处理完成之后,整个请求会有一个release的过程,即CoyoteAdapter的service方法执行完的finally块中执行release这一过程,基本如下:

finally {
if (!comet && !async || error.get()) {
request.recycle();  //注意这两行代码
response.recycle();} 
}

具体request的recycle部分代码如下:

/*** Release all object references, and initialize instance variables, in preparation for reuse of this object.*/
public void recycle() {
attributes.clear();
requestedSessionId = null;
requestedSessionURL = false;
parameterMap.clear();
pathParameters.clear();
}

我们看到用于存储setAttribute方法设置的和setParameter方法设置的数据在这里都clear掉了。这也是重定向不能够保留数据的真正原因。

forward方法

forward方法一般使用如下:

request.getRequestDispatcher("/hello.jsp").forward(request, response);

forward方法内部最终会调用dispatcher的doForward方法

void doForward(ServletRequest request, ServletResponse response){
// Set up to handle the specified request and response
State state = new State(request, response, false);wrapResponse(state);ApplicationHttpRequest wrequest =(ApplicationHttpRequest) wrapRequest(state); 
String contextPath = context.getPath();HttpServletRequest hrequest = state.hrequest;
if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) {wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO,hrequest.getPathInfo());wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());}wrequest.setContextPath(contextPath);wrequest.setRequestURI(requestURI);wrequest.setServletPath(servletPath);wrequest.setPathInfo(pathInfo);
if (queryString != null) {wrequest.setQueryString(queryString);wrequest.setQueryParams(queryString);}processRequest(request,response,state); //进行第二个资源的请求}
}

第二个资源的请求处理与一般的请求处理类似,只是在第一个请求之上,并没有返回响应时继续发起第二个请求,此时第一个请求的各类参数会继续向后传递,最终数据全部处理完成之后,整个响应发送回客户端。此时上面的release流程也依然会走,但并没有什么影响,毕竟第二个资源已经请求处理完成。
而由于浏览器发请求的时候是一个固定的URL,整个重定向是服务端内部进行的,浏览器并没有感知到,因此也不会显示出来。

整个应用服务器内部处理过程再加上清晰的定义,相信这两者的本质区别已经显露无疑。

这篇关于重定向和转发(转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1101553

相关文章

【vue3|第28期】 Vue3 + Vue Router:探索路由重定向的使用与作用

日期:2024年9月8日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083;0.98365 = 0.0006 说

在struts.xml中,如何配置请求转发和请求重定向!

<span style="font-size:18px;"><span style="white-space:pre"> </span><!--<strong>下面用请求转发action </strong>,<strong>这样过去id不会丢</strong>,如果用重定向的话,id会丢 --><result name="updatePopedom"<span style="color:#ff00

请解释JSP中的九大内置对象及其作用。什么是Java Web中的请求转发和重定向?它们有什么区别?

请解释JSP中的九大内置对象及其作用。 JSP(JavaServer Pages)中的九大内置对象(也称为隐式对象或自动对象)是JSP容器为每个页面提供的Java对象,这些对象在JSP页面被转换成Servlet时自动可用,无需显式声明。这些对象极大地简化了JSP页面的开发,因为它们提供了对Web应用程序中常见功能的直接访问。以下是九大内置对象及其作用的详细解释: request:javax.

Nginx跨域运行案例:云台控制http请求,通过 http server 代理转发功能,实现跨域运行。(基于大华摄像头WEB无插件开发包)

文章目录 引言I 跨域运行案例开发资源测试/生产环境,Nginx代理转发,实现跨域运行本机开发运行 II nginx的location指令Nginx配置中, 获取自定义请求header头Nginx 配置中,获取URL参数 引言 背景:全景监控 需求:感知站点由于云台相关操作为 http 请求,http 请求受浏览器跨域限制,不能直接访问,因此需要进行 http 的代理,实

[转发] 负载均衡的服务器集群上如何进行缓存和会话数据的管理

会话数据管理方法 1. 不存储Session 对于一些不需要记录用户状态的Web应用,采用这种Stateless方式是最恰当的方式。 2. 基于Cookie的Session共享 这种策略也被称为客户端Session,即不将Session信息存储于服务器端,而是存储于客户端。这同时,也会带来一定的安全问题,因为Cookie是存储于客户端中的,也就意味着客户端可以修改Cooki

iis7 url重写和重定向

注意不管是重写还是redirect重定向,匹配的url都要写成当前网站的url,也就是真是真实可以访问的,如当前网站ip为127.0.0.1,可以写成^127.0.0.1$ (1)url重写(可以实现伪静态) IIS实现反向代理 新建两个站点,端口分别使用 80 和 81,在DNS中新建A记录,指向该计算机(10.4.34.41) 配置过程如下: 1.在Windows Server

iis6 和iis7s上整个网站重定向

重定向作用: 重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置。举例说明:就像我XX公司,之前用的网络域名是“www.bb.com”,但是后来他们申请到了新的域名“www.ff.com”,但是你会发现当你输入之前的地址域名时候,仍然可以用,只不过他跳转到了新域名的地址下了。这也就是重定向后的作用之一。 设置步骤: IIS6下 1、 用两个简单的网站

Kubenetes 中使用 Traefik 作为 Ingress 转发流量

Kubenetes 中使用 Traefik 作为 Ingress 转发流量 Ingress 就是 Kubernetes 机器外访问集群的入口,将请求的 URL 转发到不同的 Service 上,相当于 Nginx 等代理服务器 路由信息由 Ingress Controller 提供,Ingress Controller 可以理解为监视器,不断请求 Kubernetes API 实时感知 Serv

x11转发远程图形界面

1、 开一个有vnc的节点 2、 开放所有用户的Xserver权限 xhost + 3、X11转发 ssh hlzhang@192.168.3.156 -X 4、打开远程窗口 paraview 在227的界面打开156的图形窗口

太速科技-基于Kintex-7 XC7K325T的FMC USB3.0四路光纤数据转发卡

基于Kintex-7 XC7K325T的FMC USB3.0四路光纤数据转发卡 一、板卡概述   本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持64bit DDR3容量2GByte,USB3.0接口,HPC的FMC连接器,4路光纤接口,板卡支持各种接口输入,USB3.0软件具有