Maison  >  Article  >  Java  >  Comment comparer la redirection et le transfert de requêtes à l'aide de httpclient en Java

Comment comparer la redirection et le transfert de requêtes à l'aide de httpclient en Java

PHPz
PHPzavant
2023-04-21 23:43:071087parcourir

Voici une introduction : Version HttpClient 4.x, la méthode de requête get sera automatiquement redirigée, mais la méthode de requête de publication ne sera pas automatiquement redirigée. C'est une chose à laquelle il faut prêter attention. La dernière fois que j'ai commis une erreur, c'était lorsque j'ai utilisé Post pour soumettre le formulaire de connexion, mais il n'y avait pas de redirection automatique à ce moment-là.

La différence entre le transfert de demande et la redirection

1 La redirection est deux demandes, et le transfert est une demande, donc la vitesse de transfert est plus rapide que la redirection.

2. Après la redirection, l'adresse dans la barre d'adresse changera et deviendra l'adresse demandée pour la deuxième fois. Après le transfert, l'adresse dans la barre d'adresse ne changera pas et restera l'adresse demandée pour la première fois.

3. Le transfert est un comportement de serveur et la redirection est un comportement de client. Lors de la redirection, l'URL sur le navigateur change ; lors de la redirection, l'URL sur le navigateur reste inchangée.

4. La redirection correspond à deux demandes et le transfert n'est qu'une seule demande.

5. L'URL lors de la redirection peut être n'importe quelle URL, et l'URL transférée doit être l'URL de ce site.

Ici, nous nous concentrons sur les troisième et quatrième éléments.

Le message HTTP contient le code de réponse, l'en-tête de réponse et le corps de la réponse. Seuls 200 et 302 sont mentionnés ici Code de réponse : 2xx (généralement 200). Indique que la demande a abouti, puis les données de réponse peuvent être acceptées. Code de réponse : 3xx (généralement 302). indique la redirection. Le serveur demandera au client de renvoyer une requête. Le serveur enverra un en-tête de réponse Location, qui précise l'adresse URL de la nouvelle requête. (C'est très important ! Le client doit obtenir l'adresse redirigée via l'en-tête Location. )

Il n'y a aucune mention du transfert de demande ici, car le transfert de demande est une opération côté serveur, qui est effectuée au sein du serveur. , il s'agit donc simplement d'une demande (Aucune différence avec une demande ordinaire côté client). La redirection est différente, c'est une opération client, car le serveur demande au client de renvoyer une requête, donc la redirection correspond à deux requêtes. Cela explique également pourquoi les paramètres de la requête sont perdus après la redirection, car il ne s'agit pas du tout d'une requête. Je parle ici du client, pas du navigateur, car parfois nous n'utilisons pas nécessairement le navigateur comme client. Par exemple, un robot est aussi un client.

Cependant, lorsque vous commencez à apprendre, ou pour les utilisateurs ordinaires, vous ne semblez pas sentir la différence entre les deux. Tout au plus, vous pouvez savoir si l'adresse du navigateur a changé. L'adresse du navigateur de transfert de demande reste inchangée, tandis que l'adresse du navigateur de redirection est remplacée par une nouvelle adresse. (Cependant, les deux requêtes redirigées ne sont pas reflétées dans ce processus. En effet, le navigateur nous redirige automatiquement.)

Jetons un coup d'œil à la différence entre les deux en utilisant la programmation Java :Le numéro ci-dessus. Article 3 et Article 4.

Java web part

Classe TestServlet

fournit une classe Servlet simple, sa fonctionnalité et sa simplicité, elle portera un paramètre clé, si le paramètre existe et la valeur est "1", alors la requête sera transmise à "/ dispatcher.jsp" ; sinon, redirigez vers la page "redirect.jsp".

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>

Démarrer les tests du projet

Mon objectif ici est principalement la différence d'accès entre le transfert et la redirection de requête, et non pour comparer d'autres différences entre elles, donc l'exemple est très simple.

Adresse de la demande de test : http://localhost:8080/study/TestServlet?key=1

Remarque : L'adresse de la demande n'a pas changé.

Comment comparer la redirection et le transfert de requêtes à laide de httpclient en Java

Adresse de la demande de test : http://localhost:8080/study/TestServlet?key=2 Remarque : L'adresse de la demande a changé.

Comment comparer la redirection et le transfert de requêtes à laide de httpclient en Java

Dans ce cas, vous ne voyez aucune différence d'accès entre les deux, mais si vous ne le voyez pas, cela ne veut pas dire qu'il n'y a pas de différence entre eux. méthode entre les deux via le code ci-dessous.

Utiliser HttpClient

  • 301 Déplacé de façon permanente

  • 302 Trouvé

  • 303 Voir les autres

  • 307 Redirection temporaire

Si Depuis la version HttpClient 4.x redirige automatiquement, il faut désactiver la redirection automatique afin de suivre le processus de redirection.

Définissez dans RequestConfig et définissez le délai d'attente (trois).

//HttpClient4.3中默认允许自动重定向,导致程序中不能跟踪跳转情况。
int timeout = 10*1000;
RequestConfig config = RequestConfig.custom()
		.setSocketTimeout(timeout)
		.setConnectTimeout(timeout)
		.setConnectionRequestTimeout(timeout)
		.setRedirectsEnabled(false)   //关闭自动重定向,默认值为true。
		.build();

Ensuite, définissez et autorisez la redirection automatique lors de l'envoi d'une demande.

//创建get请求对象
HttpGet getMethod = new HttpGet(url);
//设置请求方法关闭自动重定向
getMethod.setConfig(config);  //配置信息

De cette façon, lorsque nous accédons au chemin : http://localhost:8080/study/TestServlet?key=1

Le serveur transmettra la demande, mais c'est le comportement du serveur et n'a rien à voir avec le client , nous n'avons donc pas besoin de nous en soucier. Si la demande est correcte, le code de réponse est 200.

Résultats des tests :

Comment comparer la redirection et le transfert de requêtes à laide de httpclient en Java

当我们访问路径为:http://localhost:8080/study/TestServlet?key=2,服务器会要求客户端进行重定向(即要求客户端请求另一个地址),这时会先收到状态码 302,当再次访问成功时状态码为 200(当然了,也许重定向不止一次,但是浏览器会对重定向次数有限制)。

如果发生了重定向,我们需要获取响应头中的 Location 字段,这里面是重定向的地址。

//读取新的 URL 地址
Header header = response.getFirstHeader("location");
String newUrl = header.getValue();

注意:重定向是可以访问服务器外的地址的,服务器内部的地址一般是相对地址,需要拼接 URL,服务器外就是绝对 URL 了。

测试结果:

Comment comparer la redirection et le transfert de requêtes à laide de httpclient en Java

完整测试代码

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"));
								}
							}
						}
					}
				}
			} 
		}
	}
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer