Java Web之重定向和请求转发
概述
重定向和请求转发是Java Web中常用的两种实现页面跳转的技术,他们的区别可以用下图简单表示:
本文使用tomcat+jsp演示他们的区别
区别
先通过代码来直观感受一下,请求转发和重定向的区别:
请求转发
以一个登陆页面为例
这是一个登陆页面的jsp(文件名:login.jsp)↓
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="check.jsp" method="post">
用户名:<input type="text" name="uname"/><br/>
密码:<input type="password" name="upwd"/>
<input type="submit" value="登陆">
</form>
</body>
</html>
输入用户名zs和密码abc↓
这是一个校验登陆信息的jsp(文件名:check.jsp)↓
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");
if(name.equals("zs") && pwd.equals("abc")){
//请求转发,请求数据保留,地址栏不变
request.getRequestDispatcher("success.jsp").forward(request,response);
}else{
out.print("登陆失败用户名或密码有误");
}
%>
</body>
</html>
这是登陆结果页面的JSP(文件名:success.jsp)↓
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
登陆成功
欢迎宁:
<%
String name = request.getParameter("uname");
out.print(name);
%>
</body>
</html>
校验结果:
可以看到登陆成功了,显示的是success.jsp的页面,但是地址栏仍然显示是check
重定向
修改check.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");
if(name.equals("zs") && pwd.equals("abc")){
/* 1.参数写下相对路径的String对象
2.重定向请求数据会丢失
3.地址栏发生改变
*/
response.sendRedirect("success.jsp");
}else{
out.print("登陆失败用户名或密码有误");
}
%>
</body>
</html>
测试结果↓
点击登陆后↓
可以看到名字变成null了,地址栏也发生了改变
结论
请求转发能够得到按下登陆时提交的请求的值,而且地址栏不会改变。
重定向不能获得按下登陆时提交的请求的值,而且改变地址栏的值。
解析:
请求转发类似我们去药店买药:你(login.jsp)请求买药,售货员(check.jsp)了解到你的请求后,不能直接给你药,而是到药架(success.jsp)上面去取,取完回来交给你,你一直面对的都是售货员,所以地址栏没发生改变。
重定向相当于去医院看病:你(login.jsp)去挂号看医生(发出请求),医生(check.jsp)给你写开药单,之后医生就不管你了。你要自己去取药室(success.sp)取药,所以你(login.jsp)发出第二次请求(当然我们上网的时候重定向的第二次请求过程是全自动的,用户不会察觉),而取药室(success.jsp)当然不知道你的第一次请求是说了些什么,所以没有办法获得你的信息,所以你的名字当是null啦。
简要的图示如下:
请求转发 | 重定向 | |
---|---|---|
地址栏是否改变 | 不变 | 改变 |
第一次请求时数据是否保留 | 保留 | 不保留 |
请求次数 | 1 | 2 |
转跳发生位置 | 服务端(request.getRequestDispatcher( “xxx.jsp”).forward(request, response)) | 客户端发出第二次请求 (response.sendRedirect(xxx.jsp)) |