关于重定向和转发的区别

重定向和转发

用jsp的人都知道。我们常常会将数据从一个页面传到另一个页面。也就是在页面间传递控制和数据。Jsp技术的一个最基本的特性就是可以通过使用称为模型—视图—控制器(MVC) 的模型,来把整个过程划分成请求处理、商务逻辑和外观呈现三部分。一般情况下我们采用servlet来充当控制器的角色,javabean用作模封装数据的模型,用jsp来显示。有时jsp页面也同样可以充当控制器和视图的角色、此时的模型可以由bean或是jsp页面来扮演。现在很流行的做法是通过bean的形式来验证用户输入信息,如用户注册表单等。是因为我们不知道自己的用户会以哪种形式来填我们的表单,所以我们采取对用户输入进行验证的办法来检验用户输入以使用户所填信息符合我们的要求和规范。在验证的过程中我们常会把数据和控制转发向另外的页面。当用户未输入就提交或不按正规格式输入时,我们在验证到他的信息不符合规范时,就会把用户的请求转发到注册页面要求用户重新输入并打印出错误信息。我们都有在网上注册邮箱,注册成为某网站的会员。这样的情况一定见得不少。在这里不讨论用什么来验证或怎样去验证,说到这里还是先来看看转发到底是什么吧。
在jsp中有个行为元素<jsp:forward>,在jsp中就是用它来转发控制和数据的.
<jsp:forward page=”userinfo.jsp” />
这个行为将结束对一个页面的处理。而开始处理由page 属性所指定的页面。控制被转发到page所指定的页面后再也不会回到先前的页面。有关URI的内容请看后面的”关于URI”。
我们还可以使用一个或多个嵌套的<jsp:param>行为元素来加入额外的请求参数。
<jsp:forward page=”userinfo.jsp”>
<jsp:param name=”topic” value=” this topic content” />
</jsp:forward>

注意:jsp中的标准行为元素在没有行为体的情况下一定要用”/”标记结束。在有行为体的行为元素中,要用与起始行为标记同名的标签来结束,如上面的</jsp:forward>


<jsp:forward>元素可以用来转发控制。表现在如果用户没按要求填写表单,我们的验证页面可以把请求转发回注册表单页面,要求用户重新输入。通常的做法,在返回给到注册页面时用户填写正确的内容会保留在表单内,实际上<jsp:forward>在转发控制时,所有放在请求作用域中的信息都可以被处理同一请求的所有页面所使用,这就是所说的转发数据。
会看到转发实际上是把请求转向了另一个页面,但是在URL地址栏里看到的还是用户最先请求的那个URL.这一过程属于同一个请求。所以可以这样说,所有的转发都是在同一个请求中完成的,所有通过转发可以获得的数据也只有通过jsp的隐藏作用域request来得到。
用过struts的人都知道,在strtus-config.xml配置文件中都是用forward把数据转发到目标页面的,在目标页面中通过request来获得数据。

重定向(redirect)与转发相似,它们都可以把控制从一个页面传到另一个页面。但它们有很大的区别。重定向最大的一个特点就是:发送新的请求,在URL地址栏显示新的URL
重定向通常是一GET请求,所有在最初请求的页面中所获得的参数将丢失(哪怕开始是用post提交表单得来的参数也一样)。这是因为post请求参数值都放在消息主体里,而不像GET请求将参数放在URL(作为一个查询字符串)中。如果必须用到重定向又不得不携带参数的话,必须进行特殊的处理。例如:可以把从post方法提交表单得来和参数作为重定向时的查询字符串参数等。不过,这样做好像太麻烦了,一般能用表单来提交的参数都不少。那就要根据实际情况而重新选择了,可以考虑选择用转发而不用重定向。服务器重新发出请求,这时和用户主动发出的请求已经不属同一请求了,所以我们没办法去获得先前那个请求作用域中的数据。这也是它与转发的区别之一。

重定向和转发各有益处也有缺点;看看主种情况。

如果有这样的一个目录结构中:
tomcat/webapps/
test/
images/img.gif
user/login.jsp
register.jsp
在上面页面中login.jsp(登陆页面)这样引入了img.gif图片。
<img src=”../images/img.gif” />
register.jsp(注册页面)这样引入了图片。
<img src=”./images/img.gif” >
当用户示登陆时,就转发到注册页面。<jsp:forward page=”../register.jsp” >
这样来请求login.jsp页面。
http://localhost:8080/test/user/login.jsp
如果现在我是没有注册的用户,那么控制会被转发到register.jsp页面
<jsp:forward page=”../register.jsp” >,此时会在浏览器窗口中看到图片找不到没显示的图标,也就是图片出现的位置有一个方框,方框上画了一个叉。为什么会找不到,如果我们单独请求register.jsp页面时,图片显示正常。问题就出在我们用到的转发这里,上面说过。所有的转发都属同一请求。所以当转发到register.jsp页面时,它会按照我们请求login.jsp这个页面的当前路径去找那张图片。此时当前路径为user,在user目录下并没有images/img.gif这个目录。所以会找不到图片,如果把register.jsp中图片的路径改一下,像这样
<img src=”../images/img.gif”>
此时,当接到转发的请求时图片正常显示了。但当我们单独请求register.jsp注册页面时,文件路径又不对了,怎么办?这种问题在工作中也不少见吧。
由我个人的观点应该有两个解决的办法。
1, 把register.jsp中图片的路径改为绝对路径。先得出当前的上下文根,然后用绝对路径方式引用图片。
<%
String root = request.getContextPath();
%>
<img src=” <%=root %>/images/img.gif”>
//------------注意,上下文根在这里是哪种形式输出的。既然说到绝对路径就应该是以绝对路径开头的。在这里root 的输出为: /test
2,另一种解决方法是选择用重定向。由于是服务器重新发送了一次请求,就像我们直接在请求register.jsp页面一样,所以避免了找不到图片信息的这种情况的发生。但是,如果在某些需要携带参数的情况下,必须进行特殊的处理。

重定向和转发各有各的优点。具体用法要根据应用程序来灵活选择。下面是它们的区别:
转发:
不改变请求的URL,属于同一个请求。
-所有放在请求作用域中的数据都可以被同一个请求作用域中的jsp页面使用。
重定向:
发送新的请求。
通常是一个GET方法,地址栏内显示新请求的URL.
最先发送的请求所获得的数据被丢失(做特殊处理除外).


关于URI
在html中,URI被用作了<a>,<img> 和<form>这些元素的属性值。页面使用URI作为属性值的JSP元素包括page,include,tablig指令元素和<jsp:forward>和<jsp:include>行为元素。
下面就对URI的几种形式作一下简单描述。
1.绝对URI
http://localhost:8080/ora/test/test.jsp
http是案,localhos:8080是位置(一个服务器和一个端口号),ora/test/test.jsp资源路径。
在由jsp页面生成的html元素中所用到的URI是由浏览器来进行解释的。浏览器需要绝对URI,以便知道如何发送对HTML元素所引用的那些资源。它使用方案来选择正确的协议,并通过位置得知要把请求发送到什么地方。

下面是一个很简单的例子(index.jsp)
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
<%
String root = request.getContextPath();
%>
<html>
<head><title>重定向和转发</title>
</script>
<head>
<jsp:forward page=”<%=root%>/errorPage.jsp” />
<body>
<form action=”login.jsp” name = “testform” method=”post”>
<table>
<tr><td><img src = “../images/img.gif”></td></tr>
<table>
</form>
</body>
</html>


//-------------
下面是test.jsp 页面
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
<html>
<head><title>重定向和转发</title>
<script language="JavaScript" src=”./js/checkForm.js”></script>
<head>
<body>
…….
</body>
</html>

可以看到上面这个很简单的jsp页面中用到了四种uri。一起来看看吧。
src=”./js/checkForm.js”
page=” <%=root%>/errorPage.jsp”
action=”login.jsp”
src = “../images/img.gif”
我这里用到的当前路径(也就是应用程序的上下文根是test,) 服务器为tomcat,目录结构为:tomcat/
webapps/
test/
js/checkForm.js
images/img.gif
user/index.jsp
/login.jsp
test.jsp
errorPage.jsp
WEB-INF/web.xml
//--------------------------------------
src=”./js/checkForm.js”
第一种以”.”开头,这里的点代表test.jsp页面的当前路径(在这里是test)。
在url地址栏里我们这样来请求test.jsp:
http://localhost:8080/test/test.jsp
所以服务器会对src=”./js/checkForm.js”这样来解释
http://localhost:8080/test/js/checkForm.js

page=” <%=root%>/errorPage.jsp”等同于 page = “/test/errorPage.jsp”
以斜杠开头的路径。在这里jsp容器将根据应用程序的环境路径对它进行解释。在jsp规范中被称为环境相关的路径(context-relative path),它适用于程序中所有共用的资源,如这里用到的错误处理页面。如果你的页面中的图片也是共用的也可以采用这种方式。这些资源在应用程序中的目录结构中都有固定的URI.,由于绝对路径是相对于主机的,
(主机就是到http://localhost/这一层)所以在上面的目录结构中先求出了当前的上下文根.因为我们的errorPage.jsp是放在应用程序上下文根这一层目录下的。

action=”login.jsp”
不以斜杠开关的路径。将会根据使用这个URI的页面所在的位置来对这个URI进行解释。这称为页面相关的路径(page-relative path)。经常它们是在同一层目录结构中。

src = “../images/img.gif”
“.”表示当前目录,那么“..”就表示上一层目录。也就是说,如果当前目录为上下文根,那么上一层目录就会到主机那一层了。
在这里index.jsp的当前目录是user,那么它的上一层目录就是test(也就是上下文根路径)所以在这里将被这样解释:
httt://localhost:8080/images/img.gif
//----------------------
这里提到一个上下文根,在一个应用程序中只有一个上下文根,通常是在主机(localhost/)的下一层目录。在jsp页面中可以这样来得到当前jsp页面的上下文根。
<%
String root = request.getContextPath();
//此处的root就是当前页面的上下文根,测试一下吧
//可以将它打印出来看看out.println(“root=”+root);
//它的输出形式是这样的。root = /test (此处只针对上面的例子而言)
%>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值