Here is an introduction: HttpClient 4.x version, the get request method will automatically redirect, but the post request method will not automatically redirect. This is something to pay attention to. The last time I made an error was when I used post to submit the form to log in, but there was no automatic redirection at that time.
1. Redirection is two requests, and forwarding is one request, so the forwarding speed is faster than redirection.
2. After redirection, the address on the address bar will change to the address requested for the second time. After forwarding, the address on the address bar will not change and remains the address requested for the first time.
3. Forwarding is a server behavior, and redirection is a client behavior. When redirecting, the URL on the browser changes; when forwarding, the URL on the browser remains unchanged.
4. Redirection is two requests, and forwarding is only one request.
5. The URL when redirecting can be any URL, and the forwarded URL must be the URL of this site.
Here we focus on the third and fourth items.
HTTP messages include response codes, response headers and response bodies. Only 200 and 302 are mentioned here. Response code: 2xx (usually 200). Indicates that the request is successful, and then the response data can be accepted. Response code: 3xx (usually 302). indicates redirection. The server will ask the client to resend a request. The server will send a response header Location, which specifies the URL address of the new request. (This is very important! The client needs to obtain the redirected address through the Location header. )
There is no mention of request forwarding here, because request forwarding is a server-side Operation, it is performed inside the server, so it is a request (It is no different from an ordinary request on the client). Redirection is different, it is a client operation, because the server requires the client to resend a request, so redirection is two requests. This also explains why the request parameters are lost after redirection, because it is not a request at all. I am talking about the client here, not the browser, because sometimes we may not necessarily use the browser as the client. For example, a crawler is also a client.
However, for those who are just starting to learn, or for ordinary users, it seems that they cannot feel the difference between the two. At most, they can find out whether the browser address has changed. The request forwarding browser address remains unchanged, while the redirecting browser address changes to a new address. (However, the two redirected requests are not reflected in this process. This is because the browser automatically redirects us .)
Let’s take a look at the second request using Java programming. The difference between: The third and fourth items above.
Provides a simple Servlet class, its function and simplicity, it will carry a key parameter, if the parameter exists and the value is "1", then the request is forwarded to the "/dispatcher.jsp" page; otherwise, it is redirected to the "redirect.jsp" page.
package com.study; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/TestServlet") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String key = request.getParameter("key"); if((key != null && key.equals("1"))) { System.out.println("请求转发:key " + key); //请求转发 request.getRequestDispatcher("/dispatcher.jsp").forward(request,response); }else { //重定向 response.sendRedirect("redirect.jsp"); System.out.println("重定向:key " + key); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
dispacher.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>请求转发</title> </head> <body> <h2>请求转发</h2> </body> </html>
redirect.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>重定向</title> </head> <body> <h2>重定向</h2> </body> </html>
My purpose here is mainly to access the difference between request forwarding and redirection , it is not comparing other differences between them, so the example is very simple.
Test request address: http://localhost:8080/study/TestServlet?key=1
Note: The request address has not changed.
Test request address: http://localhost:8080/study/TestServlet?key=2 Note: Request address Something has changed.
In this case, you can’t see any difference in access between the two, but if you can’t see it, it doesn’t mean there is no difference between them. Let’s use the code below See the difference in access methods between the two.
301 Moved Permanently
302 Found
303 See Other
307 Temporary Redirect
Due to HttpClient 4.x The version will automatically redirect, so we must turn off automatic redirection to track the redirection process.
Set in RequestConfig and set the timeout (three).
//HttpClient4.3中默认允许自动重定向,导致程序中不能跟踪跳转情况。 int timeout = 10*1000; RequestConfig config = RequestConfig.custom() .setSocketTimeout(timeout) .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setRedirectsEnabled(false) //关闭自动重定向,默认值为true。 .build();
Then set and allow automatic redirection when sending a request.
//创建get请求对象 HttpGet getMethod = new HttpGet(url); //设置请求方法关闭自动重定向 getMethod.setConfig(config); //配置信息
In this way, when we access the path: http://localhost:8080/study/TestServlet?key=1
The server will forward the request, but this is server behavior and is different from the client It doesn't matter, so we don't need to care. If the request is correct, the response code is 200.
Test Results:
当我们访问路径为:http://localhost:8080/study/TestServlet?key=2,服务器会要求客户端进行重定向(即要求客户端请求另一个地址),这时会先收到状态码 302,当再次访问成功时状态码为 200(当然了,也许重定向不止一次,但是浏览器会对重定向次数有限制)。
如果发生了重定向,我们需要获取响应头中的 Location 字段,这里面是重定向的地址。
//读取新的 URL 地址 Header header = response.getFirstHeader("location"); String newUrl = header.getValue();
注意:重定向是可以访问服务器外的地址的,服务器内部的地址一般是相对地址,需要拼接 URL,服务器外就是绝对 URL 了。
测试结果:
package com.learn; import java.io.IOException; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.ParseException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class TestRedirect { /** * 重定向是客户端操作,而请求转发是服务端操作 。 * 但是通常用户使用浏览器,并不注意二者的区别, * 这是因为浏览器自动帮我们重定向了。(当然了, * 编程还是需要注意的)。 * @throws IOException * @throws ParseException * */ public static void main(String[] args) throws ParseException, IOException { String root = "http://localhost:8080/study/"; //网站的根路径,因为重定向得到的是相对路径(服务器内部的路径) //HttpClient4.3中默认允许自动重定向,导致程序中不能跟踪跳转情况。 int timeout = 10*1000; RequestConfig config = RequestConfig.custom() .setSocketTimeout(timeout) .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setRedirectsEnabled(false) //关闭自动重定向,默认值为true。 .build(); String url = "http://localhost:8080/study/TestServlet?key=1"; //请求转发。 //创建 httpclient 对象 CloseableHttpClient httpClient = HttpClients.createDefault(); //创建get请求对象 HttpGet getMethod = new HttpGet(url); getMethod.setConfig(config); //配置信息 //执行请求,得到响应信息 try (CloseableHttpResponse response = httpClient.execute(getMethod)) { HttpEntity entity = null; int statusCode = response.getStatusLine().getStatusCode(); System.out.println("返回值状态码:" + statusCode); if (statusCode == HttpStatus.SC_OK) { //获取请求转发的实体信息 entity = response.getEntity(); if (entity != null) { System.out.println(EntityUtils.toString(entity, "UTF-8")); } } else if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) { //读取新的 URL 地址 Header header = response.getFirstHeader("location"); System.out.println(header); if (header != null) { String newUrl = header.getValue(); if (newUrl != null && !newUrl.equals("")) { //使用get方法转向。 HttpGet redirectGet = new HttpGet(root+newUrl); System.out.println("重定向到新的地址:" + redirectGet.getURI()); redirectGet.setConfig(config); //发送请求,做进一步处理。。。 try (CloseableHttpResponse redirectRes = httpClient.execute(redirectGet)) { statusCode = redirectRes.getStatusLine().getStatusCode(); System.out.println("返回值状态码:" + statusCode); if (statusCode == HttpStatus.SC_OK) { //获取请求转发的实体信息 entity = redirectRes.getEntity(); if (entity != null) { System.out.println(EntityUtils.toString(entity, "UTF-8")); } } } } } } } } }
The above is the detailed content of How to compare redirection and request forwarding using httpclient in Java. For more information, please follow other related articles on the PHP Chinese website!