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

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

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

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

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

具体两步:

1、跳过https的验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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的简单代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

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极客

关注博客:御前提笔小书童

关注网站:HuMingfeng

关注公众号:开发者的花花世界


本作品采用知识共享署名 4.0 中国大陆许可协议进行许可,欢迎转载,但转载请注明来自御前提笔小书童,并保持转载后文章内容的完整。本人保留所有版权相关权利。

本文链接:https://royalscholar.cn/2020/08/30/《伸手系列》之CXF调用webService接口的两种方式,支持http和https/

# JAVA

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×