Java Web实战详细教程(七)转发和重定向

        在Java Web开发中有两个极为重要的概念,一个叫转发,一个叫重定向。其中转发是Java Web中特有的概念,而重定向是HTTP协议中的规定,所有的后端语言都有对应的实现,如PHP、Python等。
        下面我们详细讲解这两种技术的不同。

转发

        转发是Java Web应用程序内部做的事情,与浏览器无关。详见下图,当浏览器发送一个请求1到服务器,a.jsp处理完毕后,转发到b.jsp中处理。可以理解成HTTP的请求还未结束,所以a.jsp和b.jsp中共享一个request对象。
在这里插入图片描述
开发
        代码实践,在testWeb01项目下,新建一个dingxiang文件夹,里面新建a.jsp和b.jsp,如下图所示:
在这里插入图片描述
a.jsp代码:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>a页面</title>
</head>
<body>
	<div>a页面</div>
	<%
		//在request作用域中添加一个名为name,值为Tom的属性
		request.setAttribute("name", "Tom");
		//转发到b.jsp页面
		request.getRequestDispatcher("b.jsp").forward(request, response);
	%>
</body>
</html>

b.jsp代码:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>b页面</title>
</head>
<body>
	<div>b页面</div>
	<%
		//从作用域中,拿到name属性的值,并输出在页面上
		out.print(request.getAttribute("name"));
	%>
</body>
</html>

测试:
        在浏览器中输入localhost:8080/testWeb01/dingxiang/a.jsp,访问a.jsp,会出现如下图页面,说明转发到了b.jsp,而且正确的输出了Tom,说明在b.jsp中获取request中的name属性值,是成功的。
        注意观察浏览器的地址栏,仍然是显示的是a.jsp,这是因为对于浏览器而言,它并不知道服务器内部做了a文件与b文件的处理。
在这里插入图片描述
总结:
        转发纯粹是服务器内部做的事情,浏览器并不知晓,转发被认为是同一个request,所以共享同一个request对象。在实际应用中,往往是服务器内部需要多个文件合作处理完成一个请求的功能时,会用到转发。另外,在现代行业规范下,转发会被广泛应用在后续我们会讲到的MVC模式开发中由Servlet转到JSP页面这一情景中。

重定向

        重定向是HTTP协议的一项标准,是由浏览器和服务器共同实现的。
        通过下图,我们来看,当浏览器发送一个对a.jsp的请求时(请求1),a.jsp处理完毕,响应(响应1)给浏览器,在报头中指定status的值是302(该状态码在HTTP协议中表示重新定向),指定location的值是b.jsp,那当浏览器接收到响应1的302和b.jsp后,会自动发起一次新的请求(请求2),访问b.jsp。
        因为请求2是自动发起的,所以对用户来说可能不会切实感知,但它是经由两次网络请求,所以对于浏览器的地址栏也会及时变化为b.jsp。
在这里插入图片描述
开发
        在刚才文件中定义连个页面:c.jsp、d.jsp。
在这里插入图片描述
c.jsp代码:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>c页面</title>
</head>
<body>
	<div>c页面</div>
	<%
		//在request作用域中添加一个名为name,值为Tom的属性
		request.setAttribute("name", "Tom");
		//重定向到d.jsp页面
		response.sendRedirect("d.jsp");
	%>
	<%
		//out.println("c执行完毕");
		//System.out.println("c执行完毕");
	%>
</body>
</html>

d.jsp代码:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>d页面</title>
</head>
<body>
	<div>d页面</div>
	<%
		//从作用域中,拿到name属性的值,并输出在页面上
		out.print(request.getAttribute("name"));
	%>
	<%
		//out.println("d执行完毕");
		//System.out.println("d执行完毕");
	%>
</body>
</html>

        效果如图所示,因为重定向后所发起的请求是浏览器发起的一次新的请求,所以地址栏的地址产生变化。而正是因为这是一次新的请求,所以不会和上一次请求共享一个request对象。时期请求1的生命周期已经在发起响应1的时候已经结束了。所以request作用域中并不存在名为name的属性,所以显示为null。
在这里插入图片描述
总结:
        重定向是HTTP协议的一项规范,需要浏览器和服务器技术同时实现。可以通过浏览器的控制台的“网络”选项卡(见下图)看到它是发送了两次请求,其中对c.jsp访问,响应回status等于302,location等于d.jsp。在实际开发中,通常用于一次请求下,某个功能模块已经执行完毕,要重新定向到另一个功能模块。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/GodBlessYouAndMe/article/details/120760969