>  기사  >  Java  >  Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

PHPz
PHPz앞으로
2023-04-21 23:43:071086검색

소개는 다음과 같습니다. HttpClient 4.x 버전에서는 get 요청 메서드는 자동으로 리디렉션되지만 post 요청 메서드는 자동으로 리디렉션되지 않습니다. 이는 주의할 사항입니다. 마지막으로 오류가 발생한 것은 post를 사용하여 로그인 양식을 제출했을 때였는데, 그 당시에는 자동 리디렉션이 없었습니다.

요청 전달과 리디렉션의 차이점

1. 리디렉션은 두 개의 요청이고 전달은 하나의 요청이므로 전달 속도가 리디렉션보다 빠릅니다.

2. 리디렉션 후에는 주소 표시줄의 주소가 변경되며 두 번째 요청한 주소로 변경됩니다. 전달 후에는 주소 표시줄의 주소가 변경되지 않고 처음 요청한 주소로 유지됩니다.

3. 전달은 서버 동작이고 리디렉션은 클라이언트 동작입니다. 리디렉션하면 브라우저의 URL이 변경되고, 전달할 때는 브라우저의 URL이 변경되지 않습니다.

4. 리디렉션은 2개의 요청이고 전달은 1개의 요청입니다.

5. 리디렉션할 때 URL은 어떤 URL이든 가능하며, 전달되는 URL은 이 사이트의 URL이어야 합니다.

여기에서는 세 번째와 네 번째 항목에 중점을 둡니다.

HTTP 메시지에는 응답 코드, 응답 헤더 및 응답 본문이 포함됩니다. 여기서는 200과 302만 언급됩니다. 응답 코드: 2xx(보통 200) 요청이 성공하면 응답 데이터를 수락할 수 있음을 나타냅니다. 응답 코드: 3xx(보통 302). 는 리디렉션을 나타냅니다. 서버는 클라이언트에게 새 요청의 URL 주소를 지정하는 응답 헤더 위치를 보냅니다. (이것은 매우 중요합니다! 클라이언트는 Location 헤더를 통해 리디렉션된 주소를 얻어야 합니다. )

요청 전달은 서버 내에서 수행되는 서버 측 작업이므로 여기서는 요청 전달에 대한 언급이 없습니다. , 따라서 이는 단순한 요청입니다(클라이언트 측의 일반적인 요청과 차이가 없습니다). 리디렉션은 클라이언트 작업과 다릅니다. 서버에서는 클라이언트가 요청을 다시 보내야 하므로 리디렉션은 두 개의 요청입니다. 이는 요청이 전혀 아니기 때문에 리디렉션 후에 요청 매개변수가 손실되는 이유도 설명합니다. 여기서는 브라우저가 아닌 클라이언트에 대해 이야기하고 있습니다. 왜냐하면 때때로 우리는 브라우저를 클라이언트로 사용할 필요가 없기 때문입니다. 예를 들어 크롤러도 클라이언트이기도 합니다.

하지만 처음 학습을 시작하거나 일반 사용자의 경우 둘 사이의 차이를 거의 느끼지 못하는 것 같습니다. 브라우저 주소가 변경되었는지 여부만 알 수 있습니다. 요청 전달 브라우저 주소는 변경되지 않고 유지되지만 리디렉션 브라우저 주소는 새 주소로 변경됩니다. (단, 리디렉션된 두 요청은 이 과정에 반영되지 않습니다. 이는 브라우저가 자동으로 리디렉션하기 때문입니다.)

Java 프로그래밍을 사용하여 두 요청의 차이점을 살펴보겠습니다.위 3항과 제4조.

Java 웹 파트

TestServlet 클래스

는 간단한 서블릿 클래스, 해당 기능 및 단순성을 제공하며 주요 매개변수를 전달합니다. 매개변수가 존재하고 값이 "1"이면 요청이 "/ dispatcher.jsp" 페이지이고, 그렇지 않으면 "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>

프로젝트 테스트 시작

여기서 내 목적은 주로 요청 전달과 리디렉션 간의 액세스 차이점이지, 둘 사이의 다른 차이점을 비교하려는 것이 아니므로 예제는 매우 간단합니다.

테스트 요청 주소: http://localhost:8080/study/TestServlet?key=1

참고: 요청 주소는 변경되지 않았습니다.

Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

테스트 요청 주소: http://localhost:8080/study/TestServlet?key=2 참고: 요청 주소가 변경되었습니다.

Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

이 경우에는 둘 사이에 액세스 차이가 보이지 않지만, 보이지 않는다고 해서 액세스 차이가 없는 것은 아닙니다. 아래 코드를 통해 둘 사이의 방법.

HttpClient 사용

  • 301 영구적으로 이동됨

  • 302 발견

  • 303 기타 보기

  • 307 임시 리디렉션

HttpClient 4.x 버전은 자동으로 리디렉션되므로 자동 리디렉션을 꺼야 합니다. 리디렉션 프로세스를 추적하기 위해.

RequestConfig에서 설정하고 시간 제한(3개)을 설정하세요.

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

그런 다음 요청을 보낼 때 자동 리디렉션을 설정하고 허용하세요.

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

이 방법으로 경로에 액세스하면: http://localhost:8080/study/TestServlet?key=1

서버가 요청을 전달하지만 이는 서버 동작이며 클라이언트와는 아무 관련이 없습니다. 이므로 신경쓰지 않아도 됩니다. 요청이 정확하면 응답 코드는 200입니다.

테스트 결과:

Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

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

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

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

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

测试结果:

Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법

完整测试代码

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

위 내용은 Java에서 httpclient를 사용하여 리디렉션과 요청 전달을 비교하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제