我需要使用SSL证书通过HTTPS调用外部web服务端点。正确的方法应该是使用BindingProvider设置一个自定义的SSLSocketFactory,但我无法使其正常工作。要使连接正常工作,我必须设置一个默认的SSLSocketFactory:
public void secureStoreSignedOffPdf(String filename, byte[] signedOffPdf, URL endpoint, String applicationEnvironmentId) {
final SSLSocketFactory defaultSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
final SSLSocketFactory wsSslSocketFactory = SslHelper.buildWebServiceSslSocketFactory(applicationEnvironmentId);
// TODO Fix: this should work only setting the property with BindingProvider (see below)
HttpsURLConnection.setDefaultSSLSocketFactory(wsSslSocketFactory);
final StoragePortService storagePortService = new StoragePortService();
final StoragePort storagePort = storagePortService.getStoragePortSoap11();
final BindingProvider bindingProvider = (BindingProvider) storagePort;
bindingProvider.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint.toString());
bindingProvider.getRequestContext()
.put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
final StorageRequest storageRequest = new StorageRequest();
final Document document = new Document();
document.setContent(new DataHandler(new ByteArrayDataSource(signedOffPdf, PDF_CONTENT_TYPE)));
document.setName(filename);
storageRequest.setOverwrite(true);
storageRequest.setBaseDocument(document);
final StorageResponse storageResponse = storagePort.storage(storageRequest);
HttpsURLConnection.setDefaultSSLSocketFactory(defaultSslSocketFactory);
if (!storageResponse.getReturnCode()
.equalsIgnoreCase(RESPONSE_OK)) {
throw new IllegalStateException("Web service failed with error: "
+ storageResponse.getReturnCode()
+ " - "
+ storageResponse.getReturnMessage());
}
}
如果我删除这行:
bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
代码仍然有效(因为我正在使用HttpsURLConnection.setDefaultSSLSocketFactory方法)。但是如果我在这一行中输入了错误的SSLSocketFactory,它就会失败,所以这意味着输入factory属性会有所帮助。
我不明白的是,如果不设置默认的SSLSocketFactory,则调用无法正常工作:
HttpsURLConnection.setDefaultSSLSocketFactory(...)
仅供参考:我已经尝试过:
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
但它什么也做不了。