我使用 CXF 3.1.5,我试图让它与代理一起使用。如果代理没有用户名和密码,那么它可以工作;如果有代理的用户名和密码,那么它不起作用。这是我的代码:
//to create my own http conduit
bus.setExtension(new TLSAndProxySupportedHTTPConduitFactory(settings, HTTPConduitFactory.class);
//to get wsdl definition
Definition definition = bus.getExtension(WSDLManager.class).getDefinition(uri);
TLSAndProxySupportedHTTPConduitFactory实现 HTTPConduitFactory ,并将在TLSAndProxySupportedHTTPConduit中创建扩展 URLConnectionHTTPConduit 的TLSAndProxySupportedHTTPConduit,这是代理设置的相关代码:
//HTTPClientPolicy settings works
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setProxyServer(proxy.getHostName());
httpClientPolicy.setProxyServerPort(proxy.getPort());
this.setClient(httpClientPolicy);
if (proxy.getUserName() != null) {
//ProxyAuthorizationPolicy settings doesn't work
this.getProxyAuthorization().setUserName(proxy.getUserName());
this.getProxyAuthorization().setPassword(proxy.getPassword());
}
请注意,如果代理没有用户名和密码,一切正常。如果用https启动加载WSDL定义的目标URL(我需要https),则代理不起作用。如果它以http开头,则使用用户名和密码的代理很有效。
答案 0 :(得分:1)
找到解决方案:
原因是
Sun Microsystems的Java安全套接字扩展(JSSE)库允许您通过代理隧道从防火墙后面访问安全的Web服务器。为此,JSSE应用程序需要设置https.ProxyHost和https.ProxyPort系统属性。 JSSE中的隧道代码在代理的响应中检查“HTTP 1.0”。如果您的代理(如许多代理)返回“HTTP 1.1”,您将收到IOException。在这种情况下,您需要实现自己的HTTPS隧道协议。
全球化志愿服务青年:http://www.javaworld.com/article/2077475/core-java/java-tip-111--implement-https-tunneling-with-jsse.html
和https://community.oracle.com/thread/1534538
然后你可以覆盖URLConnectionHTTPConduit的方法setupConnection。
@Override
protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
super.setupConnection(message, address, csPolicy);
HttpURLConnection connection = (HttpURLConnection) message.get(KEY_HTTP_CONNECTION);
decorateHttpsURLConnection((HttpsURLConnection) connection);\
message.put(KEY_HTTP_CONNECTION, connection);
}
方法decorateHttpsURLConnection:
httpsConnection.setSSLSocketFactory(new SSLTunnelSocketFactory(getProxy(), sslContext.getSocketFactory()));