0

需要通过代理执行 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 资源?

4

0 回答 0