在JSP/Servlet开发中,经常会有页面跳转。而常用的两种方式,一种是Forward(转发),还有一种是Redirect(重定向)。两者也有很多不同点。
两种方式的区别不再多说,本文重点是两者的原理、实现方式的区别。
下面是两个页面test.jsp和hello.jsp,请求test.jsp时,由test.jsp分别通过Forward和Redirect两种方式跳转到hello.jsp。
hello.jsp
<html>
<body>
<h1>HELLO</h1>
</body>
</html>
test.jsp中分别使用Forward和Redirect的方式:
Forward(转发):
<%
request.getRequestDispatcher("hello.jsp").forward(request, response);
%>
Redirect(重定向):
<%
response.sendRedirect("hello.jsp");
%>
在浏览器上访问test.jsp,无论是Forward还是Redirect,都能达到显示hello.jsp页面的效果。
为了搞清楚它们本质的区别,下面实现了一个Socket实现的简单的HTTP客户端,来请求test.jsp,为了简单易读,舍去了异常处理和资源关闭的代码:
public static void main(String[] args) throws Exception
{
// 地址localhost,端口号8080
Socket socket = new Socket("localhost", 8080);
// 请求服务器
OutputStream out = socket.getOutputStream();
PrintWriter pw = new PrintWriter(out);
pw.println("GET /Test/test.jsp HTTP/1.1"); // 请求的第一行Request-Line,需要写请求的URL(/Test/test.jsp)
pw.println("Host: localhost:8080"); // 请求头,Host是必须的
pw.println(); // 一定要有个空行表示请求结束
pw.flush(); // 提交请求
// 获取服务器响应
InputStream is = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
// 输出响应内容
while (true) {
System.out.print((char)reader.read());
}
}
上面的代码通过Socket发送了一个HTTP的GET请求,请求的URL是/Test/test.jsp。
GET /Test/test.jsp HTTP/1.1
Host: localhost:8080
然后获取HTTP响应并输出。
修改test.jsp,分别使用Forward和Redirect,运行程序看输出结果。
使用Forward(转发)时输出:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=81C635B36B1C14C96BB56A2B16F39A62; Path=/Test/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 58
Date: Wed, 04 Dec 2013 09:52:46 GMT
<html>
<body>
<h1>HELLO</h1>
</body>
</html>
使用Redirect(重定向)时输出:
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=A26981A4D04D98E854933FAB8624EF16; Path=/Test/; HttpOnly
Location: http://localhost:8080/Test/hello.jsp
Content-Type: text/html
Content-Length: 0
Date: Wed, 04 Dec 2013 09:54:00 GMT
这些输出结果就是一个http响应。HTTP响应由三部分构成:
Status-Line
Header
<空行>
Message-Body
Status-Line对应的是响应内容的第一行:
HTTP/1.1 200 OK
HTTP/1.1 302 Found
Status-Line包含 HTTP版本、状态码Status-Code、原因描述Reason-Phrase三个部分,以空格隔开。
其中状态码常见的例如:200(成功),404(Not Found)、500(服务器错误)。
Header部分就是响应头,紧接在Status-Line后,是多个键值对,每个Header占一行。
Message-Body就是响应的主体,和Header部分隔着一个空行。这部分一般来说是页面的内容,例如HTML代码,或者是图片,视频等。
从服务器发回给客户端的响应可以看出,使用Forward(转发)时获取的响应是一个很正常的响应,状态码200,HTML代码是hello.jsp的代码,可以看出转发是由服务器跳转,并将跳转处理后的结果响应给客户端,客户端对这种跳转并不知情。再对比看使用Redirect(重定向),返回的响应状态码是302,而3XX状态码在HTTP协议中表示重定向,在Header部分的Location: http://localhost:8080/Test/hello.jsp表示的是重定向的地址,浏览器要在接收到这样的响应后,再重新请求跳转到Location指定的页面,这次跳转是客户端重新请求来跳转的。
作者:叉叉哥 转载请注明出处:http://blog.csdn.net/xiao__gui/article/details/17138407