You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache CXF构建Java客户端调用UKHO WebService遇问题求助

解决Apache CXF客户端调用UKHO B2B WebService的常见问题

看起来你在使用Apache CXF调用UKHO的B2B WebService时遇到了问题,我帮你梳理下常见的坑和完整的解决方案——毕竟这个服务的配置确实有几个容易踩的点:

1. 先确认服务地址的正确性

你提供的两个地址:

  • https://extenavigator.ukho.gov.uk/serviceB2B/submitUKHOOrdering.svc
  • https://extenavigator.ukho.gov.uk/ServiceB2B/SubmitUKHOOrdering.svc?singleWsdl

注意路径的大小写:serviceB2B vs ServiceB2B,WebService地址通常是严格区分大小写的。建议你先通过浏览器访问带?singleWsdl的地址,确认WSDL能正常加载,然后确保代理工厂的setAddress参数和WSDL中声明的服务地址完全一致。

2. 处理HTTPS证书信任问题

目标服务是HTTPS协议,默认情况下Java客户端会验证服务器证书。UKHO的证书虽然是公共CA签发的,但如果你的环境信任库中没有包含对应CA,或者测试环境需要快速跳过验证,可以按以下两种方式处理:

测试环境:临时跳过证书验证(不推荐生产使用)

给CXF的HTTP客户端添加自定义信任配置,忽略证书和主机名检查:

import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.frontend.ClientProxy;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

// 创建代理后获取HTTP管道
IOrderingService client = (IOrderingService) proxyFactory.create();
HTTPConduit conduit = (HTTPConduit) ClientProxy.getClient(client).getConduit();

TLSClientParameters tlsParams = new TLSClientParameters();
// 自定义信任管理器:信任所有证书
TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { return null; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
    }
};
try {
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
    tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
    tlsParams.setDisableCNCheck(true); // 禁用主机名匹配检查
} catch (Exception e) {
    e.printStackTrace();
    return;
}
conduit.setTlsClientParameters(tlsParams);

生产环境:导入证书到信任库

从浏览器访问服务地址,导出服务器证书,然后导入到Java默认信任库:

keytool -importcert -file ukho_service_cert.cer -keystore $JAVA_HOME/jre/lib/security/cacerts -alias ukho-b2b-service

默认信任库密码为changeit,导入后客户端会自动信任该证书。

3. 添加B2B服务的认证信息

UKHO的SubmitUKHOOrdering服务几乎肯定需要身份认证,最常见的是Basic认证。如果是这种情况,给HTTP管道添加认证配置:

import org.apache.cxf.transport.http.auth.DefaultBasicAuthSupplier;

// 继续上面的HTTPConduit配置
conduit.getAuthorization().setUserName("你的UKHO用户名");
conduit.getAuthorization().setPassword("你的UKHO密码");
conduit.getAuthorization().setAuthorizationType("Basic");
// 设置Basic认证供应商
conduit.setAuthSupplier(new DefaultBasicAuthSupplier());

如果服务要求WS-Security认证,你需要额外添加CXF的安全模块依赖,并配置对应的策略,不过UKHO的B2B服务大多用Basic认证,先优先尝试这个。

4. 完整的客户端示例代码

把上面的配置整合起来,完整的可运行代码大概是这样:

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.auth.DefaultBasicAuthSupplier;
import org.apache.cxf.frontend.ClientProxy;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class UKHOOrderClient {
    public static void main(String[] args) {
        JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
        proxyFactory.setServiceClass(IOrderingService.class);
        // 注意地址大小写和WSDL一致
        proxyFactory.setAddress("https://extenavigator.ukho.gov.uk/ServiceB2B/SubmitUKHOOrdering.svc");
        
        // 创建客户端代理
        IOrderingService client = (IOrderingService) proxyFactory.create();
        
        // 配置HTTP管道
        HTTPConduit conduit = (HTTPConduit) ClientProxy.getClient(client).getConduit();
        
        // 处理HTTPS证书(生产环境请替换为信任库导入方式)
        TLSClientParameters tlsParams = new TLSClientParameters();
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
            tlsParams.setDisableCNCheck(true);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        conduit.setTlsClientParameters(tlsParams);
        
        // 配置Basic认证
        conduit.getAuthorization().setUserName("你的UKHO用户名");
        conduit.getAuthorization().setPassword("你的UKHO密码");
        conduit.getAuthorization().setAuthorizationType("Basic");
        conduit.setAuthSupplier(new DefaultBasicAuthSupplier());
        
        // 调用服务方法
        try {
            // 示例:构造请求并调用
            OrderRequest request = new OrderRequest();
            // 填充请求参数...
            OrderResponse response = client.submitOrder(request);
            System.out.println("服务响应:" + response);
        } catch (Exception e) {
            // 打印详细异常,包括SOAP Fault信息
            e.printStackTrace();
        }
    }
}

5. 其他排查要点

  • 确认wsdl2java生成的代码正确:建议用带?singleWsdl的地址重新生成,命令示例:
    wsdl2java -p com.yourcompany.ukho https://extenavigator.ukho.gov.uk/ServiceB2B/SubmitUKHOOrdering.svc?singleWsdl
    
    确保生成的IOrderingService接口和实体类没有编译错误。
  • 检查CXF依赖完整性:如果用Maven,确保pom.xml包含必要依赖:
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.6.2</version> <!-- 使用最新稳定版 -->
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-security</artifactId>
            <version>3.6.2</version>
        </dependency>
    </dependencies>
    
  • 检查网络连通性:确认你的机器能访问目标服务地址,没有防火墙或代理拦截。

如果还是有问题,一定要捕获并打印完整的异常栈(包括SOAP Fault的详细信息),这能帮你快速定位是认证错误、参数错误还是其他问题。

内容的提问来源于stack exchange,提问作者D.yan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:43:59