java http请求设置代理Proxy的两种常见方法

 更新时间:2023年11月25日 14:35:58   作者:几层山下  
代理是一种常见的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问,这篇文章主要给大家介绍了关于java http请求设置代理Proxy的两种常见方法,需要的朋友可以参考下

HttpURLConnection、HttpClient设置代理Proxy

有如下一种需求,原本A要给C发送请求,但是因为网络原因,需要借助B才能实现,所以由原本的A->C变成了A->B->C。

这种情况,更多的见于内网请求由统一的网关做代理然后转发出去,比如你本地的机器想要对外上网,都是通过运营商给的出口IP也就是公网地址实现的。这种做法就是代理了。

研究了一下针对 HttpURLConnection和HttpClient这两种常见的http请求的代理:

一、HttpURLConnection设置请求代理

贴出一个utils类

具体代码如下:

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

上面的代码就是对httpsURLConnection设置了Proxy代理,也就是请求先会发到proxyHost:proxyPort,然后由其代理发到url。

二、HttpClient设置请求代理

贴出一个utils类

具体代码如下:

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

以上就是针对http、https的代理汇总,其实想想,就是通过 Proxy 对象,添加对应的代理地址和端口,实现了一层转发,可以想到nginx、gateway这种思想。

总结

到此这篇关于java http请求设置代理Proxy的两种常见方法的文章就介绍到这了,更多相关java http请求设置代理Proxy内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Mybatis的PageHelper分页工具的教程详解

    使用Mybatis的PageHelper分页工具的教程详解

    这篇文章主要介绍了使用Mybatis的PageHelper分页工具的教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 一文详解Lombok中@ToString()的使用技巧

    一文详解Lombok中@ToString()的使用技巧

    在平时我们工作的时候,我们经常会使用toString() 方法来输出一个对象的一些属性信息。Lombok 给我们提供了一个自动生成 toString()代码的注解,可以减少代码行数,本文就来和大家详细聊聊吧
    2023-02-02
  • SpringMVC将请求和响应的数据转换为JSON格式的几种方式

    SpringMVC将请求和响应的数据转换为JSON格式的几种方式

    这篇文章主要给大家介绍饿了SpringMVC将请求和响应的数据转换为JSON格式的几种方式,文中通过代码示例和图文结合给大家介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-11-11
  • Java中的Set接口实现类HashSet和LinkedHashSet详解

    Java中的Set接口实现类HashSet和LinkedHashSet详解

    这篇文章主要介绍了Java中的Set接口实现类HashSet和LinkedHashSet详解,Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了,需要的朋友可以参考下
    2024-01-01
  • Mybatis 一对多和多对一关联查询问题

    Mybatis 一对多和多对一关联查询问题

    这篇文章主要介绍了Mybatis 一对多和多对一关联查询问题,需要的朋友可以参考下
    2017-04-04
  • java实现简单学生管理系统项目

    java实现简单学生管理系统项目

    这篇文章主要介绍了java实现简单学生管理系统项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 学习Java的9张思维导图

    学习Java的9张思维导图

    这篇文章主要为大家详细介绍了学习Java的9张思维导图,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • SpringBoot静态资源CSS等修改后再运行无效的解决

    SpringBoot静态资源CSS等修改后再运行无效的解决

    这篇文章主要介绍了SpringBoot静态资源CSS等修改后再运行无效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • spring boot实现超轻量级网关的方法(反向代理、转发)

    spring boot实现超轻量级网关的方法(反向代理、转发)

    这篇文章主要介绍了spring boot实现超轻量级网关(反向代理、转发)的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • jquery对输入框内容的数字校验代码实例

    jquery对输入框内容的数字校验代码实例

    这篇文章主要介绍了jquery对输入框内容的数字校验代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09

最新评论