CXF 客户端使用java.net.URLConnection 连接到服务。可以通过这种方式配置 URLConnection 选择本地 IP 地址(见How can I specify the local address on a java.net.URLConnection?)
URL url = new URL(yourUrlHere);
Proxy proxy = new Proxy(Proxy.Type.DIRECT,
new InetSocketAddress(
InetAddress.getByAddress(
new byte[]{your, ip, interface, here}), yourTcpPortHere));
URLConnection conn = url.openConnection(proxy);
我检查了工件 cxf-rt-rs-client 和 cxf-rt-transports-http 的代码以了解 CXF 如何创建连接。在ProxyFactory 中是用于创建UrlConnection 所需的Proxy 对象的代码
private Proxy createProxy(final HTTPClientPolicy policy) {
return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()),
new InetSocketAddress(policy.getProxyServer(),
policy.getProxyServerPort()));
}
如您所见,没有办法配置IP地址,所以问题的答案恐怕是不能用CXF配置源IP地址
但是,我认为修改源代码以允许设置源IP地址并不难
HTTPClientPolicy
将以下代码添加到org.apache.cxf.transports.http.configuration.HTTPClientPolicycxf-rt-transports-http
public class HTTPClientPolicy {
protected byte[] sourceIPAddress;
protected int port;
public boolean isSetSourceIPAddress(){
return (this.sourceIPAddress != null);
}
代理工厂
将以下代码修改为org.apache.cxf.transport.http.ProxyFactorycxf-rt-transports-http
//added || policy.isSetSourceIPAddress()
//getProxy() calls finally to createProxy
public Proxy createProxy(HTTPClientPolicy policy, URI currentUrl) {
if (policy != null) {
// Maybe the user has provided some proxy information
if (policy.isSetProxyServer() || policy.isSetSourceIPAddress())
&& !StringUtils.isEmpty(policy.getProxyServer())) {
return getProxy(policy, currentUrl.getHost());
} else {
// There is a policy but no Proxy configuration,
// fallback on the system proxy configuration
return getSystemProxy(currentUrl.getHost());
}
} else {
// Use system proxy configuration
return getSystemProxy(currentUrl.getHost());
}
}
//Added condition to set the source IP address (is set)
//Will work also with a proxy
private Proxy createProxy(final HTTPClientPolicy policy) {
if (policy.isSetSourceIPAddress()){
Proxy proxy = new Proxy(Proxy.Type.DIRECT,
new InetSocketAddress(
InetAddress.getByAddress(
policy.getSourceIPAddress(), policy.getPort()));
} else {
return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()),
new InetSocketAddress(policy.getProxyServer(),
policy.getProxyServerPort()));
}
}
用法
Client client = ClientProxy.getClient(service);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setSourceIPAddress(new byte[]{your, ip, interface, here}));
httpClientPolicy.setPort(yourTcpPortHere);
http.setClient(httpClientPolicy);