点击上方"开发者的花花世界",选择"设为星标"技术干货不定时送达!
最近发现一个旧项目的调用webservice接口不支持HTTPS,故支持一下,顺便分享一波
目前一般做这种通用的接口调用,对于HTTPS的接口一般都是忽略验证,直接跳过;
本文基于WSDL的webservice接口地址开发
具体两步:
1、跳过https的验证
private static void trustAllHosts() {TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {@Overridepublic java.security.cert.X509Certificate[] getAcceptedIssuers() {return new java.security.cert.X509Certificate[]{};}@Overridepublic void checkClientTrusted(java.security.cert.X509Certificate[] chain,String authType) {}@Overridepublic void checkServerTrusted(java.security.cert.X509Certificate[] chain,String authType) {}}};try {SSLContext sc = SSLContext.getInstance("TLS");sc.init(null, trustAllCerts, new SecureRandom());HttpsURLConnection.setDefaultSSLSocketFactory(new MyCustomSSLSocketFactory(sc.getSocketFactory()));HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}});} catch (Exception e) {e.printStackTrace();}}/*** We need to invoke sslSocket.setEnabledProtocols(new String[] {"SSLv3"});* see http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html (Java 8 section)*/// SSLSocketFactory用于创建 SSLSocketsprivate static class MyCustomSSLSocketFactory extends SSLSocketFactory {private final SSLSocketFactory delegate;public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {this.delegate = delegate;}// 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。// 这些默认的服务的最低质量要求保密保护和服务器身份验证@Overridepublic String[] getDefaultCipherSuites() {return delegate.getDefaultCipherSuites();}// 返回的密码套件可用于SSL连接启用的名字@Overridepublic String[] getSupportedCipherSuites() {return delegate.getSupportedCipherSuites();}@Overridepublic Socket createSocket(final Socket socket, final String host, final int port,final boolean autoClose) throws IOException {final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);return overrideProtocol(underlyingSocket);}@Overridepublic Socket createSocket(final String host, final int port) throws IOException {final Socket underlyingSocket = delegate.createSocket(host, port);return overrideProtocol(underlyingSocket);}@Overridepublic Socket createSocket(final String host, final int port, final InetAddress localAddress,final int localPort) throwsIOException {final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);return overrideProtocol(underlyingSocket);}@Overridepublic Socket createSocket(final InetAddress host, final int port) throws IOException {final Socket underlyingSocket = delegate.createSocket(host, port);return overrideProtocol(underlyingSocket);}@Overridepublic Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,final int localPort) throwsIOException {final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);return overrideProtocol(underlyingSocket);}private Socket overrideProtocol(final Socket socket) {if (!(socket instanceof SSLSocket)) {throw new RuntimeException("An instance of SSLSocket is expected");}((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1"});return socket;}}
2、跳过cn验证
if (url.startsWith("https") || url.startsWith("HTTPS")) {TLSClientParameters tcp = new TLSClientParameters();tcp.setTrustManagers(new TrustManager[] { new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1) {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[] {};}} });tcp.setDisableCNCheck(true);tcp.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}});conduit.setTlsClientParameters(tcp);}
最后上一下获取client的简单代码示例
public Client getClient(String url) throws ClientInitException {try {// 生成url对应的keyString key = Utils.bytesToHexString(url.getBytes(encode));Client client = clientMap.get(key);if (client == null) {/*** 设置跳过https的验证*/if (url.startsWith("https") || url.startsWith("HTTPS")) {trustAllHosts();}// 创建动态客户端 通过服务JSON获取地址创建客户client = dcf.createClient(url);HTTPConduit conduit = (HTTPConduit) client.getConduit();HTTPClientPolicy policy = new HTTPClientPolicy();policy.setConnectionTimeout(10000); //连接超时时间policy.setReceiveTimeout(120000);//请求超时时间.conduit.setClient(policy);/*** 设置是否跳过cn验证*/if (url.startsWith("https") || url.startsWith("HTTPS")) {TLSClientParameters tcp = new TLSClientParameters();tcp.setTrustManagers(new TrustManager[] { new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1) {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[] {};}} });tcp.setDisableCNCheck(true);tcp.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}});conduit.setTlsClientParameters(tcp);}// 多个客户端应该用下面的方法// dcf.createClient(url, serviceName);// 需要密码的情况需要加上用户名和密码// client.getOutInterceptors().add(new// ClientLoginInterceptor(USER_NAME,// PASS_WORD));clientMap.put(key, client);}return client;} catch (Exception e) {throw new ClientInitException("获取webservice客户端错误", e);}}
关注Github:1/2极客[1]
关注博客:御前提笔小书童[2]
关注网站:HuMingfeng[3]
关注公众号:开发者的花花世界
References
[1]
1/2极客: https://github.com/humingfeng[2]
御前提笔小书童: https://blog.csdn.net/qq_22260641[3]
HuMingfeng: https://royalscholar.cn
喜欢就点个"在看"呗^_^
文章转载自开发者的花花世界,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





