暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

《伸手系列》之CXF调用webService接口的两种方式,支持http和https

开发者的花花世界 2021-02-20
528

点击上方"开发者的花花世界",选择"设为星标"技术干货不定时送达!

最近发现一个旧项目的调用webservice接口不支持HTTPS,故支持一下,顺便分享一波

目前一般做这种通用的接口调用,对于HTTPS的接口一般都是忽略验证,直接跳过;

本文基于WSDL的webservice接口地址开发

具体两步:

1、跳过https的验证

private static void trustAllHosts() {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}


@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
}


@Override
public 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() {
@Override
public 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用于创建 SSLSockets
private static class MyCustomSSLSocketFactory extends SSLSocketFactory {


private final SSLSocketFactory delegate;


public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
}


// 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
// 这些默认的服务的最低质量要求保密保护和服务器身份验证
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}


// 返回的密码套件可用于SSL连接启用的名字
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}




@Override
public 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);
}




@Override
public Socket createSocket(final String host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
}


@Override
public Socket createSocket(final String host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
return overrideProtocol(underlyingSocket);
}


@Override
public Socket createSocket(final InetAddress host, final int port) throws IOException {
final Socket underlyingSocket = delegate.createSocket(host, port);
return overrideProtocol(underlyingSocket);
}


@Override
public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,
final int localPort) throws
IOException {
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() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
}


@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
}


@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
} });
tcp.setDisableCNCheck(true);
tcp.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
conduit.setTlsClientParameters(tcp);
}

最后上一下获取client的简单代码示例



public Client getClient(String url) throws ClientInitException {


try {


// 生成url对应的key
String 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() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
}


@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
}


@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
} });
tcp.setDisableCNCheck(true);
tcp.setHostnameVerifier(new HostnameVerifier() {
@Override
public 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论