尝试使用JAVA OKHttp发布到rest API。
我的代码如下:
try {
loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build();
MediaType mediaType = MediaType.parse("app.lication/json");
RequestBody body = RequestBody.create(mediaType, FileUtils.readFileToString(file));
Request request = new Request.Builder()
.url(restAPIUrl)
.post(body)
.addHeader("content-type", "application/json")
.addHeader("cache-control", "no-cache")
.build();
Call call = client.newCall(request);
call.execute();
handleResponse(file, response.code());
} catch (Exception e) {
logger.severe("Http Request failed: " + e.getMessage());
}
在没有防火墙打开的本地开发盒(centos)上,每个东西都按预期运行。 call.execute()抛出异常:无法解析主机:名称或服务不可用。
在防火墙打开的生产盒(rhel)上。该方法调用client.newCall(request);只是无限期地挂起来。 (在调用execute()之前)strace只显示等待的线程。
我已经验证我可以从命令行到达其余的API:
curl -X get https://restAPIUrl/index.html
同一个jar在两台服务器上的行为不同。我无法弄清楚为什么服务器配置的差异会影响newCall()(我会更期望它在执行时)由于环境而导致newCall()挂起的原因是什么?任何帮助将非常感激。
谢谢!
更新:
如果我覆盖defaultSocketFactory,我发现它超过了newCall()方法。
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.setSocketFactory(new SocketFactory () {
@Override
public Socket createSocket(String s int i) thorws IOException, UnknownHostException {
return null;
}
.
.
})
.build();
为什么系统不能使用rhel env上的defaultSocketFactory为客户端正确分配套接字? (SELINUX禁用。)
更新2:解决方案
最后,此问题是由$ JAVA_HOME / lib / security中的'local_policy.jar'没有读取权限引起的。 (我的开发环境中不存在文件)
令人讨厌的部分是OKHttp API吞噬了权限异常。
尝试按照"Update your security provider to protect against SSL exploits"中的说明修补安全提供程序。
只需实施ProviderInstaller.installIfNeeded
(或installIfNeededAsync
)