背景

遇到一个客户,他的宿主机可以通过配置环境变量联通外网,但是容器默认不继承宿主机的环境变量,导致容器联不通外网,因此需要单独给容器配置,但是配置后,依然还有问题。
原因是 java 本身的请求不会默认走代理代理,除非现在是全局的代理。否则,只是在环境变量中的 http_proxy 这种是没有用的。

httpClient 方案

Use HttpClientBuilder and set flag useSystemProperties:

HttpClient client = HttpClientBuilder.create().useSystemProperties().build();

then you have two options at least:

Option A: Override arguments, i.e.

java -Djava.net.useSystemProxies=true 
     -Dhttp.proxyHost=PROXY_HOST
     -Dhttp.proxyPort=PROXY_PORT 
     -Dhttp.proxyUser=USERNAME
     -Dhttp.proxyPassword=PASSWORD
     -jar your-app.jar

源码

com.fr.third.org.apache.http.impl.client.HttpClientBuilder#build

HttpRoutePlanner routePlannerCopy = this.routePlanner;
if (routePlannerCopy == null) {
    SchemePortResolver schemePortResolverCopy = this.schemePortResolver;
    if (schemePortResolverCopy == null) {
        schemePortResolverCopy = DefaultSchemePortResolver.INSTANCE;
    }
    if (proxy != null) {
        routePlannerCopy = new DefaultProxyRoutePlanner(proxy, schemePortResolverCopy);
    } else if (systemProperties) {
        routePlannerCopy = new SystemDefaultRoutePlanner(
                schemePortResolverCopy, ProxySelector.getDefault());
    } else {
        routePlannerCopy = new DefaultRoutePlanner(schemePortResolverCopy);
    }
}

URLConnection 方案

if (instProxy == null) { // no instance Proxy is set  
    /**     * Do we have to use a proxy?     */    ProxySelector sel =  
        java.security.AccessController.doPrivileged(  
            new java.security.PrivilegedAction<ProxySelector>() {  
                public ProxySelector run() {  
                         return ProxySelector.getDefault();  
                     }  
                 });  
    if (sel != null) {

可以看到,默认在不配置 Proxy 的情况下, 是会走到 ProxySelector.getDefault() 中。
这里会自动捕获配置的代理