프록시를 사용한 Java의 HTTP 요청
Java에서 HTTP 호출을 수행하기 위한 간편한 기본 제공 솔루션은 없습니다. 많은 패키지가 몇 가지 관련 기능을 제공하지만 하나를 선택하기가 쉽지 않습니다. 특히 인증된 프록시를 통한 연결과 같은 추가 기능이 필요한 경우.
Apache HttpComponents 프로젝트의 일부인
fluent.Request
를 사용하여 기본 요청에서 고급 기능으로 이동합니다.직접 요청
첫 번째 단계는 원하는 페이지를 요청하는 것입니다. 데모용으로 httpbin을 사용하겠습니다. 헤더와 원본 IP를 표시하여 요청이 성공했는지 확인할 수 있습니다.
Request
를 가져와 대상 페이지를 가져오고 결과를 문자열로 추출해야 합니다. 패키지는 이러한 경우 및 더 많은 경우에 대한 방법을 제공합니다. 마지막으로 응답을 인쇄합니다.import org.apache.hc.client5.http.fluent.Request;
public class TestRequest {
public static void main(final String... args) throws Exception {
String url = "http://httpbin.org/anything";
String response = Request
.get(url) // use GET HTTP method
.execute() // perform the call
.returnContent() // handle and return response
.asString(); // convert response to string
System.out.println(response);
}
}
응답을 처리하거나 오류를 확인하지 않습니다. 실제 사용 사례의 단순화된 버전입니다.
그러나 결과에서 요청이 성공했음을 알 수 있으며 IP가 원본으로 표시됩니다. 잠시 후에 해결해 드리겠습니다.
프록시 요청
보안이나 익명성과 같은 HTTP 요청에 프록시를 추가하는 데는 여러 가지 이유가 있습니다. 어쨌든 Java 라이브러리는 (보통) 프록시 추가를 복잡하게 만듭니다.
우리의 경우 인증이 필요하지 않은 한 프록시 URL과 함께
viaProxy
를 사용할 수 있습니다. 나중에 자세히 설명합니다.지금은 무료 목록의 프록시를 사용합니다. 이들free proxies이 작동하지 않을 수 있습니다. 수명이 짧습니다.
import org.apache.hc.client5.http.fluent.Request;
public class TestRequest {
public static void main(final String... args) throws Exception {
String url = "http://httpbin.org/anything";
String proxy = "http://169.57.1.85:8123"; // Free proxy
String response = Request.get(url)
.viaProxy(proxy) // will set the passed proxy
.execute().returnContent().asString();
System.out.println(response);
}
}
인증을 통한 프록시
ZenRows과 같은 유료 또는 개인 프록시 공급자는 각 호출에서 인증을 자주 사용합니다. 때로는 IP 허용 목록을 통해 수행되지만
Proxy-Authorization
헤더와 같은 다른 수단을 사용하는 경우가 많습니다.적절한 인증 방법 없이 프록시를 호출하면
Exception in thread "main" org.apache.hc.client5.http.HttpResponseException: status code: 407, reason phrase: Proxy Authentication Required
오류가 발생합니다.예제에 따라 인증과 프록시를 호스트로 전달하는 두 가지가 필요합니다.
Proxy-Authorization
에는 base64로 인코딩된 사용자 및 비밀번호가 포함되어 있습니다.그런 다음
viaProxy
가 사용자 및 암호가 포함된 URL을 허용하지 않으므로 프록시를 가져오는 방법을 변경해야 합니다. 이를 위해 전체 URL을 전달하는 새HttpHost
를 생성합니다. 내부적으로 문제를 처리하고 불필요한 부분을 생략합니다.import java.net.URI;
import java.util.Base64;
import org.apache.hc.client5.http.fluent.Request;
import org.apache.hc.core5.http.HttpHost;
public class TestRequest {
public static void main(final String... args) throws Exception {
String url = "http://httpbin.org/anything";
URI proxyURI = new URI("http://YOUR_API_KEY:@proxy.zenrows.com:8001"); // Proxy URL as given by the provider
String basicAuth = new String(
Base64.getEncoder() // get the base64 encoder
.encode(
proxyURI.getUserInfo().getBytes() // get user and password from the proxy URL
));
String response = Request.get(url)
.addHeader("Proxy-Authorization", "Basic " + basicAuth) // add auth
.viaProxy(HttpHost.create(proxyURI)) // will set the passed proxy as a host
.execute().returnContent().asString();
System.out.println(response);
}
}
SSL 인증서 무시
SSL(https) 연결에 프록시를 추가할 때 라이브러리는 인증서에 대한 경고/오류를 발생시키는 경향이 있습니다. 보안 관점에서 보면 정말 대단합니다! 우리는 피하고 싶은 사이트가 표시되거나 리디렉션되는 것을 피합니다.
그러나 우리 자신의 프록시를 통해 연결을 강제하는 것은 어떻습니까? 이러한 경우에는 보안 위험이 없으므로 이러한 경고를 무시하려고 합니다. 즉, 다시 말하지만 Java에서는 쉬운 작업이 아닙니다.
오류는 다음과 같습니다.
Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
.이 경우 대상 URL을
https
로 전환하여 수정합니다. 또한 다음에 만들 도우미 메서드를 호출합니다. 기본 기능에서 다른 변경 사항은 없습니다.public class TestRequest {
public static void main(final String... args) throws Exception {
ignoreCertWarning(); // new method that will ignore certificate warnings
String url = "https://httpbin.org/anything"; // switch to https
// ...
}
}
이제 복잡하고 장황한 부분으로 넘어갑니다. SSL 컨텍스트와 가짜 인증서를 만들어야 합니다. 보시다시피 인증서 관리자와 해당 메서드는 아무 작업도 수행하지 않습니다. 내부 작업을 우회하여 문제를 피할 수 있습니다. 마지막으로 생성된 가짜 인증서로 컨텍스트를 초기화하고 기본값으로 설정합니다. 이제 가도 좋습니다!
import java.security.cert.X509Certificate;
import javax.net.ssl.*;
public class TestRequest {
// ...
private static void ignoreCertWarning() {
SSLContext ctx = null;
TrustManager[] trustAllCerts = new X509TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
} };
try {
ctx = SSLContext.getInstance("SSL");
ctx.init(null, trustAllCerts, null);
SSLContext.setDefault(ctx);
} catch (Exception e) {}
}
}
결론
Java에서 데이터 액세스(또는 스크래핑)는 복잡하고 장황해질 수 있습니다. 그러나 올바른 도구와 라이브러리를 사용하여 인증서의 장황함을 길들일 수 있었습니다.
나중에 이 주제로 다시 돌아올 수 있습니다. HttpComponents 라이브러리는 비동기 및 다중 스레드 실행과 같은 매력적인 기능을 제공합니다.
Reference
이 문제에 관하여(프록시를 사용한 Java의 HTTP 요청), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/anderrv/http-requests-in-java-with-proxies-30n8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)