背景
遇到一个客户,他的宿主机可以通过配置环境变量联通外网,但是容器默认不继承宿主机的环境变量,导致容器联不通外网,因此需要单独给容器配置,但是配置后,依然还有问题。
原因是 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() 中。
这里会自动捕获配置的代理