Java Socket实现HTTP客户端来理解Redirect和Forward区别

在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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值