尝试使用JAVA OKHttp发布到restAPI。
我的代码如下:
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());
}
在没有对restAPI打开防火墙的本地开发盒(centos)上,所有事情的行为均符合预期。 call.execute()引发异常:无法解析主机:名称或服务不可用。
在生产框(rhel)上,其中防火墙已打开。对client.newCall(request);的方法调用无限期地挂起。 (在调用execute()之前)strace仅显示线程正在等待。
我已经验证可以通过以下命令从命令行访问restAPI:
curl -X get https://restAPIUrl/index.html
同一罐子在两个服务器上的行为不同。我不知道为什么服务器配置上的差异会影响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
)