美文网首页
Java HTTP代理

Java HTTP代理

作者: 码中仙 | 来源:发表于2019-10-07 16:09 被阅读0次

1. 专有云访问公网资源

最近一个部署在专有云的项目上线后,需要访问公网资源,客户专有云环境对外网访问控制比较严格,开放一个代理服务器可访问外网。

2. Linux 上通过Http代理访问

在Linux上需要下载公网的资源,只要指定https_proxy和https_proxy即可,我们测试一下是否可行

#设置http/htts代理
[root@iZvy205enekymwo01x4w3vZ test]# export https_proxy=10.145.9.74:3128
[root@iZvy205enekymwo01x4w3vZ test]# export http_proxy=10.145.9.74:3128
# 查看是否走到代理
[root@iZvy205enekymwo01x4w3vZ test]# curl -v -o /dev/null -s https://www.taobao.com
* About to connect() to proxy 10.145.9.74 port 3128 (#0)
*   Trying 10.145.9.74...
* Connected to 10.145.9.74 (10.145.9.74) port 3128 (#0)
* Establish HTTP proxy tunnel to www.taobao.com:443

# 查看请求时间
[root@iZvy205enekymwo01x4w3vZ ~]# curl -o /dev/null -s -w %{time_namelookup}:%{time_connect}:%{time_starttransfer}:%{time_total}:%{speed_download}"\n" https://www.taobao.com
0.000:0.002:0.190:0.286:514182.000

各参数的含义
time_namelookup - DNS服务器解析时间,单位秒
time_connect - client 发出请求,到 c/s 建立TCP 的时间;里面包括 DNS 解析的时间
time_starttransfer - client 发出请求;到 server 响应发出第一个字节开始的时间;包括前面的2个时间
time_total - client 发出请求;到 server 把响应的数据全部发送给 client;并关闭 connect 的时间
speed_download - 下载速率

3. Java应用中使用HTTP代理

在Java应用中,常用的有两种http客户端实现

  • Java自带的HttpUrlConnection
  • Apache的HttpClient
    这两种实现设置代理的方式有一些区别
3.1 HttpUrlConnection代理
3.1.1 设置JVM启动参数
 -Dhttp.proxyHost=10.145.9.74 -Dhttp.proxyPort=3128 -Dhttps.proxyHost=10.145.9.74 -Dhttps.proxyPort=3128

该方式会将所有使用HttpUrlConnection做http客户端的请求都走代理,对HttpClient无效。在专有云上使用访问内部资源也会走到代理,这样可能会带来问题。我们需要能控制访问外网的请求走代理,下面我们来看看在代码里如何实现。

3.1.2 Proxy
URL url = new URL("https://www.taobao.com");
Proxy proxy = new Proxy(Proxy.Type.DIRECT.HTTP, new InetSocketAddress("10.145.9.74", 3128));  
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);

该方式简单,但是对于已经封装好的二方库,我们没办法去修改代码,JDK提供了一种代理选择机制

3.1.3 ProxySelector
//实现代理选择器,根据域名选择代理服务器
public class MyProxySelector extends ProxySelector {
    private List<Proxy> proxyList = Lists.newArrayList(new Proxy(Type.HTTP, InetSocketAddress.createUnresolved("10.145.9.74", 3128)));
    
    private ProxySelector defaultProxy = ProxySelector.getDefault();
    @Override
    public void connectFailed(URI uri, SocketAddress address, IOException e) {
         //代理出错处理
    }
 
    @Override
    public List<Proxy> select(URI uri) {
        String host = uri.getHost().toLowerCase();
        if(host.endsWith("taobao.com")){
            return proxyList;
        }else{
            return defaultProxy;
        }
    }
}
//设置系统默认代理服务器
ProxySelector.setDefault(new MyProxySelector());

ProxySelector机制所有采用HttpUrlConnection实现http的请求都会经过select方法,在这里可以根据URI来决定是否走代理。
对于HttpUrlConnection实现的http请求,ProxySelector可以完美解决,但是Apache HttpClient实现默认情况下无效,我们看看Apache HttpClient如何实现代理。

3.2 Apache HttpClient代理
3.2.1 为单个请求设置代理
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory 
    = new HttpComponentsClientHttpRequestFactory(
        HttpClientBuilder.create()
                .setProxy(new HttpHost("10.145.9.74", 3128, "http"))
                .build());
clientHttpRequestFactory.getHttpClient().execute(request);
3.2.2 根据URI选择代理服务器,也是使用ProxySelector
HttpRoutePlanner routePlanner = new SystemDefaultRoutePlanner(new MyProxySelector());

HttpComponentsClientHttpRequestFactory clientHttpRequestFactory 
    = new HttpComponentsClientHttpRequestFactory(
        HttpClientBuilder.create()
            .setRoutePlanner(routePlanner)
            .build());
3.2.3 使用系统默认ProxySelector
HttpRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault());

    HttpClient httpClient = HttpClientBuilder
            .create()
            .setRoutePlanner(routePlanner)
            .build();
  • 3.2.2和3.2.3本质上是一样的,应用中同时存在HttpUrlConnection和Apache HttpClient两种实现,可以采用3.2.3来统一实现代理选择。
  • Apache HttpClient 第三方库中如果没有提供指定代理的设置接口,只能修改代码了,没办法像HttpUrlConnection那样统一拦截。

相关文章

  • Java 中的HTTP/Socks代理设置

    在内网环境,有些时候需要设置Java代理,常见的有HTTP(s)代理和Socks代理,如何设置代理,Java 可以...

  • Java HTTP代理

    1. 专有云访问公网资源 最近一个部署在专有云的项目上线后,需要访问公网资源,客户专有云环境对外网访问控制比较严格...

  • java实现简单的http代理

    java http代理 初学java就写了个http代理练练手,把以前C语言写的移植了下,不得不说Java写起来是...

  • 动态代理

    Java 中的动态代理 源码分析实现原理的过程: http://blog.csdn.net/bluetjs/art...

  • 谈谈Java中的代理

    摘要: 原创出处 http://peijie2016.gitee.io 欢迎转载,保留摘要,谢谢! 代理是Java...

  • java动态代理(JDK和cglib)(转载自http://ww

    java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是...

  • 五、抓包工具

    1、HTTP代理 (1) 所谓的http代理,其实就是代理客户机的http访问,主要代理浏览器访问页面。 代理服务...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • <译> Retrofit

    原文:一种针对 Android 和 Java 的类型安全的 HTTP 代理 简介 Retrofit 可以将 HTT...

  • 基于Netty的HTTP代理

    HTTP代理协议 HTTP代理分为两种模式:HTTP模式、隧道(TUNNEL)模式。 HTTP模式 客户端会将代理...

网友评论

      本文标题:Java HTTP代理

      本文链接:https://www.haomeiwen.com/subject/xhympctx.html