How to compare redirection and request forwarding using httpclient in Java
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.
The difference between request forwarding and redirection
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.
Java web part
TestServlet class
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 id="请求转发">请求转发</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 id="重定向">重定向</h2> </body> </html>
Start project test
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.
Using HttpClient
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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

The reasons why PHP is the preferred technology stack for many websites include its ease of use, strong community support, and widespread use. 1) Easy to learn and use, suitable for beginners. 2) Have a huge developer community and rich resources. 3) Widely used in WordPress, Drupal and other platforms. 4) Integrate tightly with web servers to simplify development deployment.
