经常有人会问,我们的服务器在内网,不想让服务器拥有外网IP前提下访问阿里云的OpenAPI可以吗?今天我们对此进行一个解答。在文章中,我们使用最新的阿里云Java SDK:com.aliyun:aliyun-java-sdk-core:4.5.20
。
文章的示例代码中,代理假设为192.168.1.1:8888,具体代理,包括下面示例里用到的用户名、密码请在开发、测试时改为对应的正确配置。
1. 阿里云Java SDK支持的HTTP客户端
阿里云Java SDK的HTTP客户端在com.aliyuncs.http.HttpClientFactory.buildClient(IClientProfile)
中进行初始化,当前支持四种不同的客户端,定义在枚举类com.aliyuncs.http.HttpClientType中:
Compatible
:传统的Java自带的Http客户端,用java.net
进行HTTP访问;ApacheHttpClient
:Apache Httpclient
客户端的实现,是阿里云Java SDK的默认实现;OkHttp
:OkHttp
客户端,当前暂不支持,不可用;Custom
:自定义客户端
因此,理论上,只要使用的HTTP客户端实现支持代理,那么阿里云Java SDK也支持代理。再不济,自定义客户端可以进行魔改。
2. 通用代理设置方式
2.1 环境变量中配置代理
阿里云Java SDK支持HTTP_PROXY
、HTTPS_PROXY
、NO_PROXY
三个系统环境变量(注意大小写)。这些变量通过System.getEnv()
读入。需要注意的是,使用System.setProperty()
设置的变量是无效的。
在Linux系统中临时配置环境变量,可执行:
export HTTP_PROXY=http://192.168.1.1:8888
export HTTPS_PROXY=https://192.168.1.1:8888
然后正常初始化com.aliyuncs.IAcsClient
即可。这种方式对代码无侵入,可写到应用启动脚本中。
2.2 代码中指定代理
阿里云Java SDK支持在代码中配置代理,并且配置的代理优先级高于环境变量中的配置:
// 配置HTTP客户端
HttpClientConfig config = HttpClientConfig.getDefault();
config.setHttpProxy("http://192.168.1.1:8888");
config.setHttpsProxy("https://192.168.1.1:8888");
// 配置SDK Profile
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
profile.setHttpClientConfig(config);
// 生成Client实例
IAcsClient client = new DefaultAcsClient(profile);
3. 针对特定实现的代理设置方式
3.1 HttpClientType.Compatible
代理
HttpClientType.Compatible
代理没有特殊的配置地方,参考2. 通用代理配置方式
即可。启动HttpClientType.Compatible
的方式可以是
// 配置HTTP客户端
HttpClientConfig config = HttpClientConfig.getDefault();
config.setClientType(HttpClientType.Compatible); // config.setCompatibleMode(true)也可以
也可以是:
// 配置HTTP客户端
HttpClientConfig config = HttpClientConfig.getDefault();
config.setCompatibleMode(true)也可以
3.2 HttpClientType.ApacheHttpClient
代理
Apache Httpclient作为功能丰富的HTTP客户端,支持更多灵活的代理,包括各种代理认证。这里对以用户名/密码的代理进行示例:
// 配置HTTP客户端
HttpClientConfig config = HttpClientConfig.getDefault();
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope("192.168.1.1", 8888),
new UsernamePasswordCredentials("username", "password")); //请替换为真实的用户名/密码
config.setExtParam("apache.httpclient.builder", HttpClientBuilder.create()
.setProxy(new HttpHost("192.168.1.1", 8888))
.setDefaultCredentialsProvider(credentialsProvider));
// 配置SDK Profile
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
profile.setHttpClientConfig(config);
// 生成Client实例
DefaultAcsClient client = new DefaultAcsClient(profile);
这里直接把构造好的org.apache.http.impl.client.HttpClientBuilder
(注意是HttpClientBuilder
,不是HttpClient
)塞到HttpClientConfig
的extParam
里,阿里云Java SDK在com.aliyuncs.http.clients.ApacheHttpClient.initHttpClientBuilder()
把HttpClientBuilder
取出。那么,想要怎么配,和阿里云Java SDK已经无关了,直接看Apache httpClient的文档,一切皆可配。