cxf客户端调用Webservice接口报错:java.lang.NoSuchFieldError: QUALIFIED

本文记录了在使用CXF客户端调用WebService过程中遇到的一个异常及其解决过程。通过排除jar包冲突,最终定位到两个相似的xmlSchema相关jar包导致的问题,并成功解决了调用异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        最近遇到生产环境xfire客户端调用webservice接口总是超时出错,非常麻烦,遂动手优化客户端调用工具,思来想去选择了cxf客户端调用,于是乎开始了漫长的调试过程,其中一个错误真是把我整的够呛,废话不多说先上异常:


        解决方案之前说下我调用客户端引入的jar包啊,同样截图(红框内是必须的):

                                                           

    百度了下,基本可以认定是jar包冲突,由于开始使用xfire客户端引入了一个wstx-asl-3.2.8.jar的包和我新引入的woodstox-core-asl-4.4.1.jar是冲突的,很开心的删除了这个jar,但是一调试,立马绿了。还是报同样的错误,想到根本问题没有解决,仍从jar冲突下手,仔细分析了堆栈的异常涉及到很多的xmlSchema的错误,想到会不会是xml相关的jar包,遂仔细分析以前工程导入的jar包终于发现一个xmlSchema-1.4.5.jar的包和我导入的xmlSchema-core-2.1.0.jar十分相似,遂抱着试试看的态度删除,测试,成功了!!!!

      第一篇博客,经验分享给大家,希望可以帮到大家!

<think>嗯,用户遇到了在使用Apache CXF的HTTPConduit调用WebService时出现&ldquo;appkey is null&rdquo;的SoapFault错误。我需要帮他解决这个问题。首先,我应该回顾一下常见的导致这个错误的原因。通常,SOAP头中的认证信息缺失或格式不正确会引发此类错误。用户提到服务端验证需要正确的soapHeader,比如引用[2]中的结构:<check><entryStr>value</entryStr></check>,所以客户端必须正确添加这个头信息。 接下来,我需要考虑Apache CXF中如何添加SOAP头。可能的方式有两种:使用JAX-WS的Handler或者直接通过CXF的拦截器。用户可能没有正确配置这些部分,导致appkey没有传递过去。例如,在客户端代码中,可能需要创建SOAP头并包含必要的appkey节点。 另外,HTTPConduit的配置是否正确?比如是否启用了正确的HTTP策略,或者有没有设置必要的HTTP头部。不过这里的错误是关于SOAP头的,所以可能和HTTP头无关,但也不能完全排除。例如,有些服务可能需要同时在HTTP头和SOAP头中添加认证信息,但根据引用[2],问题主要集中在SOAP头的结构上。 可能的解决步骤:首先,检查客户端代码是否正确生成并添加了SOAP头。然后,确认SOAP头的结构是否符合服务端要求,特别是命名空间是否正确。有时候,手动构造SOAP头时可能会遗漏命名空间,导致服务端无法解析。此外,使用工具如SoapUI来测试请求,确保手动构造的请求能够成功,从而排除客户端代码的问题。 另外,查看服务端的日志或错误信息是否有更详细的提示,但用户可能无法访问服务端日志,所以需要从客户端入手。如果使用拦截器,可能需要检查拦截器的逻辑是否正确,是否在发送请求前正确添加了头部。 还有,引用[1]中的例子是使用wsdl2java生成客户端代码,用户是否使用了类似的工具?生成的客户端是否有自动处理SOAP头的方法,或者需要手动添加?如果生成的代码没有包含必要的头部信息,用户需要手动添加,比如通过BindingProvider或自定义拦截器。 最后,考虑是否配置了正确的策略(Policy)在HTTPConduit中,比如是否需要启用MTOM或其他特性,但这些可能和当前问题无关。主要焦点应该是在SOAP头的正确性和存在性上。</think>### 分析&ldquo;appkey is null&rdquo;错误的解决方案 根据错误描述和引用内容,该问题通常是由于SOAP请求头(Header)中缺少身份验证信息(如`appkey`)或格式不符合服务端要求导致的[^2]。以下是分步解决方案: --- #### **1. 确保SOAP头正确添加** 服务端要求SOAP头包含类似以下结构的身份验证信息: ```xml <soapenv:Header> <check> <entryStr>appkey_value</entryStr> </check> </soapenv:Header> ``` **实现方法**(以CXF为例): - **通过拦截器添加SOAP头**: ```java import org.apache.cxf.binding.soap.SoapHeader; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.w3c.dom.Element; public class AppKeyInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String appKey; public AppKeyInterceptor(String appKey) { super(Phase.PRE_PROTOCOL); this.appKey = appKey; } @Override public void handleMessage(SoapMessage message) throws Fault { try { // 创建SOAP头元素 Element entryStr = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument().createElement(&quot;entryStr&quot;); entryStr.setTextContent(appKey); Element check = entryStr.getOwnerDocument().createElement(&quot;check&quot;); check.appendChild(entryStr); // 添加到SOAP头 SoapHeader header = new SoapHeader(new QName(&quot;check&quot;), check); message.getHeaders().add(header); } catch (Exception e) { throw new Fault(e); } } } // 使用拦截器 Client client = ClientProxy.getClient(yourPort); client.getOutInterceptors().add(new AppKeyInterceptor(&quot;your_appkey&quot;)); ``` --- #### **2. 验证HTTPConduit配置** 确保HTTP请求的基础配置正确(如超时、编码等): ```java import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.configuration.security.AuthorizationPolicy; // 获取HTTPConduit Client client = ClientProxy.getClient(yourPort); HTTPConduit conduit = (HTTPConduit) client.getConduit(); // 设置HTTP基础认证(如需) AuthorizationPolicy auth = new AuthorizationPolicy(); auth.setUserName(&quot;username&quot;); auth.setPassword(&quot;password&quot;); conduit.setAuthorization(auth); // 设置超时 HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setConnectionTimeout(10000); policy.setReceiveTimeout(10000); conduit.setClient(policy); ``` --- #### **3. 检查命名空间(Namespace)** 如果服务端要求特定的命名空间,需在SOAP头中显式声明: ```xml <check xmlns=&quot;http://example.com/namespace&quot;> <entryStr>appkey_value</entryStr> </check> ``` 在代码中创建元素时需指定命名空间: ```java Element entryStr = doc.createElementNS(&quot;http://example.com/namespace&quot;, &quot;entryStr&quot;); ``` --- #### **4. 使用SoapUI调试** 通过工具手动验证请求结构: 1. 在SoapUI中导入WSDL文件。 2. 添加SOAP头: ```xml <check> <entryStr>your_appkey</entryStr> </check> ``` 3. 发送请求,观察是否仍报错。若成功,则问题出在客户端代码;若失败,联系服务端确认格式要求。 --- #### **5. 确认服务端WSDL兼容性** 若使用`wsdl2java`生成客户端代码(如引用[1]),需确保生成的代码与服务端版本一致: ```bash wsdl2java -p com.your.package -d /output/path -client -encoding utf-8 http://service/wsdl ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值