java http request setting proxy Proxy

HttpURLConnection, HttpClient set proxy Proxy

There is the following requirement. Originally A wanted to send a request to C, but due to network reasons, it needed the help of B to achieve it, so the original A->C became A->B->C.

This situation is more common when internal network requests are proxied by a unified gateway and then forwarded. For example, if your local machine wants to access the Internet, it is achieved through the export IP, which is the public network address, given by the operator. This approach is called agency.

I studied proxies for two common http requests, HttpURLConnection and HttpClient:

1. HttpURLConnection sets request proxy

Post a utils class

The specific code is as follows:

public class ProxyUtils {
    
    

    public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";

    public static String getResultByHttpConnectionProxy(String url, String content, String proxyHost, int proxyPort) {
    
    

        String result = "";
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
    
    
            //设置proxy
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
            URL proxyUrl = new URL(url);
            //判断是哪种类型的请求
            if (url.startsWith("https")) {
    
    
                HttpsURLConnection httpsURLConnection = (HttpsURLConnection) proxyUrl.openConnection(proxy);
                httpsURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
                //允许写入
                httpsURLConnection.setDoInput(true);
                //允许写出
                httpsURLConnection.setDoOutput(true);
                //请求方法的类型 POST/GET
                httpsURLConnection.setRequestMethod("POST");
                //是否使用缓存
                httpsURLConnection.setUseCaches(false);
                //读取超时
                httpsURLConnection.setReadTimeout(15000);
                //连接超时
                httpsURLConnection.setConnectTimeout(15000);
                //设置SSL
                httpsURLConnection.setSSLSocketFactory(getSsf());
                //设置主机验证程序
                httpsURLConnection.setHostnameVerifier((s, sslSession) -> true);

                outputStream = httpsURLConnection.getOutputStream();
                outputStream.write(content.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                inputStream = httpsURLConnection.getInputStream();
            } else {
    
    
                HttpURLConnection httpURLConnection = (HttpURLConnection) proxyUrl.openConnection(proxy);
                httpURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setUseCaches(false);
                httpURLConnection.setConnectTimeout(15000);
                httpURLConnection.setReadTimeout(15000);

                outputStream = httpURLConnection.getOutputStream();
                outputStream.write(content.getBytes("UTF-8"));
                outputStream.flush();
                inputStream = httpURLConnection.getInputStream();
            }

            byte[] bytes = read(inputStream, 1024);
            result = (new String(bytes, "UTF-8")).trim();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (outputStream != null) {
    
    
                    outputStream.close();
                }
                if (inputStream != null) {
    
    
                    inputStream.close();
                }
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        return result;
    }

    public static byte[] read(InputStream inputStream, int bufferSize) throws IOException {
    
    
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[bufferSize];

        for (int num = inputStream.read(buffer); num != -1; num = inputStream.read(buffer)) {
    
    
            baos.write(buffer, 0, num);
        }

        baos.flush();
        return baos.toByteArray();
    }

    private static SSLSocketFactory getSsf() {
    
    
        SSLContext ctx = null;
        try {
    
    
            ctx = SSLContext.getInstance("TLS");
            ctx.init(new KeyManager[0],
                    new TrustManager[]{
    
    new ProxyUtils.DefaultTrustManager()},
                    new SecureRandom());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        assert ctx != null;
        return ctx.getSocketFactory();
    }

    private static final class DefaultTrustManager implements X509TrustManager {
    
    
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
    
    
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
    
    
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
    
    
            return null;
        }
    }
}

The above code sets a Proxy proxy for httpsURLConnection, that is, the request will first be sent to proxyHost:proxyPort, and then sent to the url by its proxy.

2. HttpClient sets request proxy

Post a utils class

The specific code is as follows:

public class HttpclientUtils {
    
    

    private static final String CONTENT_TYPE = "application/x-www-form-urlencoded";

    public static String getResultByProxy(String url, String request, String proxyHost, int proxyPort) throws Exception {
    
    
        String response = null;
        HttpPost httpPost = null;
        try {
    
    
            HttpClient httpClient = getHttpClient(url);
            //设置请求配置类  重点就是在这里添加setProxy 设置代理
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000)
                    .setConnectionRequestTimeout(15000).setProxy(new HttpHost(proxyHost, proxyPort)).build();
            httpPost = new HttpPost(url);
            
            httpPost.setConfig(requestConfig);
            httpPost.addHeader("Content-Type", CONTENT_TYPE);
            httpPost.setEntity(new StringEntity(request, "utf-8"));

            response = getHttpClientResponse(httpPost, httpClient);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (null != httpPost) {
    
    
                httpPost.releaseConnection();
            }
        }
        return response;
    }

    private static String getHttpClientResponse(HttpPost httpPost, HttpClient httpClient) throws Exception {
    
    
        String result = null;
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();

        if (null != entity) {
    
    
            try (InputStream inputStream = entity.getContent()) {
    
    
                byte[] bytes = read(inputStream, 1024);
                result = new String(bytes, StandardCharsets.UTF_8);
            }
        }

        return result;
    }

    private static HttpClient getHttpClient(String url) throws Exception {
    
    
        HttpClient httpClient;
        String lowerURL = url.toLowerCase();
        if (lowerURL.startsWith("https")) {
    
    
            httpClient = createSSLClientDefault();
        } else {
    
    
            httpClient = HttpClients.createDefault();
        }
        return httpClient;
    }

    private static CloseableHttpClient createSSLClientDefault() throws Exception {
    
    
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, (s, sslSession) -> true);
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }

    public static byte[] read(InputStream inputStream, int bufferSize) throws IOException {
    
    
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[bufferSize];

        for (int num = inputStream.read(buffer); num != -1; num = inputStream.read(buffer)) {
    
    
            baos.write(buffer, 0, num);
        }

        baos.flush();
        return baos.toByteArray();
    }
}

The above is a summary of proxies for http and https. In fact, if you think about it, you can add the corresponding proxy address and port through the Proxy object to achieve a layer of forwarding. You can think of ideas such as nginx and gateway.

Everyone is welcome to discuss and learn. My abilities are limited and I am still exploring. I welcome corrections if there are any mistakes.

Guess you like

Origin blog.csdn.net/qq_38653981/article/details/129066422