springboot使用时pom文件引用包:
<!-- cxf Web Service -->

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>4.0.2</version>
    </dependency>

在使用apache cxf调用C#的webservice时出现的几种错误及解决办法:
A.出现undefined element declaration 's:schema'
这是java调用net写的webservice服务端,C#的soap协议封装标签名称和java soap标签不一致导致
解决办法:
1.先将webservice的wsdl下载到本地(用浏览器访问https://xxxwebservice.asmx?wsdl并右键保存成xml)或保存成xx.wsdl、xx.xml (经实测文件的后缀名其实关系不大,都可以正常生成)
2、修改 wsdl 文档以下内容:
将文件中所有的 <s:element ref="s:schema" /><s:any /> 替换成 <s:any minOccurs="2" maxOccurs="2"/>
3.使用文件路径调用createClient即可:
System.getProperty("user.dir") + "/src/main/resources/config/aaa.wsdl";

B.出现No operation was found with the name错误
出现此类错误是因为请求参数命名空间不一致导致,需要修改成如下代码,也可以将postman中使用的xml作为string类型参数传递过去,这里不再举例,只展示代码修改方式。
C.另外还有在调用完成后,返回的result[0]类型不是String类型,是any类型,导致无法序列化
这个问题困扰了我一天,google中无法有效搜索到解决方案,最后在youxia的blog中受到启发,先用Object[] result = client.invoke("getDatabaseInfo");

        System.out.println(result.getClass());

查看返回类型,想到序列化就能转成string,使用Json读取Object转String序列化解决。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValueAsString(result[0]);

之后解析读取xml即可,使用dom4j或者其他方式均可,这块百度一下就可以了;
也有看到weigbo的解决方案,但我没尝试:
https://blog.csdn.net/weigbo/article/details/6321923
B和C错误解决方案一并放入如下代码:

public static void sendWebServiceOp(String url, String method, long receivetimeout, Object... param) {
        try {
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            Client client = dcf.createClient(url);
            HTTPConduit conduit = (HTTPConduit) client.getConduit();
            HTTPClientPolicy policy = new HTTPClientPolicy();
            //long timeout = 20 * 60 * 1000;
            policy.setConnectionTimeout(5000);
            policy.setReceiveTimeout(receivetimeout);
            conduit.setClient(policy);

            // 下面一段处理 WebService接口和实现类namespace不同的情况
            // CXF动态客户端在处理此问题时,会报No operation was found with the name的异常
            Endpoint endpoint = client.getEndpoint();
            QName opName = new QName(endpoint.getService().getName().getNamespaceURI(), method);
            BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
            if (bindingInfo.getOperation(opName) == null) {
                for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
                    if (method.equals(operationInfo.getName().getLocalPart())) {
                        opName = operationInfo.getName();
                        break;
                    }
                }
            }
            Object[] objects = client.invoke(opName, param);
            ObjectMapper objectMapper = new ObjectMapper();
            String result = objectMapper.writeValueAsString(objects[0]);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
            LoggerUtil.LOGGER.error("call web service error:call method: " + method, e);
        }

    }

单元测试调用

@Test
    public void testwebservice() {
        System.out.println(System.getProperty("user.dir"));
        String genCfg = System.getProperty("user.dir") + "/src/main/resources/config/aaa.wsdl";
String[] params = {"AA","BB","CC"};
        JaxWsClientUtil.sendWebServiceOp(genCfg,"method",20 * 60 * 1000, params);
    }

最后在使用中我出现的问题有传入参数不细心,参数类型不对,以及返回时各种问题没详细排查
另外使用cxf的时候要小心大数据超长,可能会出现超大数据导致cxf message无法handler,这块我没有遇到,但是我同事说返回空字符,这块还没具体解决方案,暂时就这么多吧

https://www.cnblogs.com/piaopiaoqun/p/6171155.html
https://blog.51cto.com/u_16099274/9598726
https://blog.csdn.net/youxiaF/article/details/118695605

water_hai
1 声望0 粉丝