需要通过代理执行 REST 请求。有几个 HTTP 代理服务器可用,受基本身份验证保护。使用 Java 16。
访问 HTTP 资源时完全正常工作的请求示例:
var proxySettings = new ProxySettings("http", "proxy.ip.address", proxy.port, "userName", "password");
var request = HttpRequest.newBuilder(new URI("http://tv-games.ru")).build();
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress(proxySettings.getUri(), proxySettings.port())))
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(proxySettings.userName(), proxySettings.getPasswordArray());
}
}).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Body: " + response.body());
System.out.println("Code: " + response.statusCode());
这是一个携带有关代理服务器信息的对象:
public record ProxySettings(String scheme, String hostname, int port, String userName, String password) {
public char[] getPasswordArray() {
return password.toCharArray();
}
public String getUri() {
return scheme + "://" + hostname;
}
}
请求 HTTPS 资源时,例如https://yandex.ru,我收到错误 407(需要代理身份验证)。
我目前正在使用基于 Apache HttpClient 5 的解决方法:
HttpHost targetHost = new HttpHost("https", "yandex.ru");
HttpHost proxyHost = new HttpHost(proxySettings.scheme(), proxySettings.hostname(), proxySettings.port());
//Create the HttpGet request object
HttpGet httpget = new HttpGet("/");
httpget.setConfig(RequestConfig.custom().setProxy(proxyHost).build());
//Create the CloseableHttpClient
CredentialsStore credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(proxySettings.hostname(), proxySettings.port()),
new UsernamePasswordCredentials(proxySettings.userName(), proxySettings.getPasswordArray()));
CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build();
//Get the result
CloseableHttpResponse closeableHttpResponse = client.execute(targetHost, httpget);
System.out.println("Body: " + EntityUtils.toString(closeableHttpResponse.getEntity()));
System.out.println("Code: " + httpResponse.code());
EntityUtils.consume(closeableHttpResponse.getEntity());
但是,Apache HttpClient 依赖项相当重量级,我真的很想留在纯 Java 的框架内。
是否可以使用内置的 HttpClient 通过代理访问 HTTPS 资源?