使用CXF调用WSDL

article/2025/9/13 20:55:01

简介

时隔多年,再次遇到需要调用WebService的业务,对方给予的wsdl说明文档还是内网的链接,并且设有基础访问权限,即在浏览器打开wsdl链接时需要输入【用户名+密码】登录后方可查看wsdl文档,这需要设置代理(我使用putty完成了代理),本文只记录使用org.apache.cxf调用wsdl的过程

附一张putty的下载链接:

https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

步骤一 :添加org.apache.cxf的maven引用

        <!-- cxf JaxWsDynamicClientFactory 开始 --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.5.2</version></dependency><!-- cxf JaxWsDynamicClientFactory 结束 -->

步骤二:访问WSDL

/*** 打开WSDL文件* @return*/private static Bus openWSDL(){Bus bus = BusFactory.getThreadDefaultBus();bus.setExtension((name, address, httpConduit) -> {//设置访问wsdl所需的用户名和密码final AuthorizationPolicy authorization = new AuthorizationPolicy();authorization.setUserName("username");authorization.setPassword("password");httpConduit.setAuthorization(authorization);final HttpAuthSupplier supplier = new DefaultBasicAuthSupplier();httpConduit.setAuthSupplier(supplier);//设置service中location的映射代理IP和端口 final HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();httpClientPolicy.setProxyServer("127.0.0.1");httpClientPolicy.setProxyServerPort(50000);httpClientPolicy.setAllowChunking(false);httpClientPolicy.setConnectionTimeout(50000);httpClientPolicy.setReceiveTimeout(50000);httpConduit.setClient(httpClientPolicy);}, HTTPConduitConfigurer.class);return bus;}

步骤三:获取WSDL文档内容

/*** 获取WSDL内容* @return*/private static Map<String,Object> getWSDLContent() {Map<String,Object> wsdl = new HashMap<>();try {Bus bus = openWSDL();ClassLoader loader = Gmm1020Server.class.getClassLoader();// 创建动态客户端JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(bus);Client client = dcf.createClient("你的wsdl地址",new QName("wsdl中的targetNamespace", "wsdl:service的name"),loader,new QName("wsdl中的targetNamespace", "HTTP_Port"));QName qName = new QName("wsdl中的targetNamespace", "wsdl:operation的name");List<MessagePartInfo> partInfos = client.getEndpoint().getService().getServiceInfos().get(0).getBinding(new QName("wsdl中的targetNamespace", "wsdl:binding的name")).getOperation(qName).getInput().getMessageParts();wsdl.put("client",client);wsdl.put("qname",qName);wsdl.put("messagePartInfo",partInfos);} catch (Exception e) {throw new WebServiceException(e);}return wsdl;}

注意:Bus引用的是上一个方法

Bus bus = openWSDL();

步骤四:调用远程接口(远程过程调用)

/*** 调用远程过程*/public static void call(Map map) {Map<String,Object> wsdl = getWSDLContent();Client client = (Client) wsdl.get("client");List<MessagePartInfo> partInfos = (List<MessagePartInfo>) wsdl.get("messagePartInfo");QName qName = (QName) wsdl.get("qname");String clazzName = partInfos.get(0).getTypeClass().getName();try {Object requestParamObject = Thread.currentThread().getContextClassLoader().loadClass(clazzName).newInstance();Field[] fields = requestParamObject.getClass().getDeclaredFields();for (Field field : fields) {//如果是泛型boolean b = field.getGenericType() instanceof ParameterizedType;if(b && field.getType() == List.class){Type[] types = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();for (Type type : types) {Class aClass = (Class) type;Object obj = aClass.newInstance();List<Object> curElementList = new ArrayList<>();List<Map> params = (List<Map>) map.get(field.getName().toLowerCase());if(!CollectionUtils.isEmpty(params)){for (Map param : params) {writeFiledVal(obj,param);curElementList.add(obj);}}//writeCustomValue(obj);field.setAccessible(true);field.set(requestParamObject,curElementList);}}else if(field.getType().getName().equals("java.lang.String")){//字符串则直接赋值Field f = requestParamObject.getClass().getDeclaredField(field.getName());f.setAccessible(true);f.set(requestParamObject,map.get(f.getName()));}else {//对象类型Class clazz = field.getType();Object obj = clazz.newInstance();Map param = (Map) map.get(field.getName().toLowerCase());writeFiledVal(obj,param);//writeCustomValue(obj);Field f = requestParamObject.getClass().getDeclaredField(field.getName());f.setAccessible(true);f.set(requestParamObject,obj);}}log.info("请求参数:{}",JSON.toJSON(requestParamObject));Object result = client.invoke(qName, requestParamObject);log.info("响应结果:{}",JSON.toJSONString(result,true));} catch (Exception e) {throw new RuntimeException(e);}}

注意:该代码的入参是一个Map对象,该对象中包含了三种类型的属性和一层属性对象的嵌套(java.util.List、java.lang.String、POJO对象)因此该代码只针对三种类型做了解析处理,并不具备所有类型的通用性。

比如:你的入参对象中有java.lang.Integer类型,或者Set ...,那就需要编写相应的解析方式,这是类型解析。

属性对象的嵌套的意思是:如果你的入参对象Map中有个List<POJO>或者直接就是POJO,这就是一层属性嵌套,而如果这个List中的POJO对象又嵌套了其他的POJO对象,这就属于二层解析,即:

List<User> userList = new ArrayLIst();

class User {

private String userName;

private UserDetails userDetails;

}

而或许UserDetails对象中还存着Enterprise对象... 以此嵌套,想要全面解析你就需要使用递归算法。(我想我应该把问题说清楚了)

代码层面:ParameterizedType

Type[] types = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();

这个对象是一个接口,表示参数化类型,这句代码意思是返回这个field的实际类型参数

步骤五:字段赋值

    /*** 字段写值* @param obj*/private static void writeFiledVal(Object obj,Map param) {Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {field.setAccessible(true);try {field.set(obj,param.get(field.getName()));} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}/*** 测试使用* 给字段写入自定义值* @param obj*/private void writeCustomValue(Object obj) {Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {field.setAccessible(true);if(!field.getType().isPrimitive()){field.getType().getConstructors();}try {field.set(obj,"1");} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}

说明:writeCustomValue是测试方式,而writeFiledVal多了一个入参Map,主要用来赋值的。

使用的时候,只需要讲你的入参对象转换成map,放入 'call()' 方法即可完成调用

 

响应结果虽然是服务器告诉我有问题(因为我的数据是乱写的),但是可以看得出来,调用是通了 


http://chatgpt.dhexx.cn/article/jICiOkTc.shtml

相关文章

spring5.x cxf3.4.x 服务端和客户端 非maven版本

文章目录 一、资料准备1. 官网链接2. 解压3. 依赖梳理 二、spring集成cxf2.1.创建spring项目2.2. 创建接口2.3. impl2.4. spring-cxf.xml2.5. 客户端2.6. 开源项目 一、资料准备 1. 官网链接 http://cxf.apache.org/download.html 下载apache-cxf-3.4.5.zip 2. 解压 3. 依赖…

CXF实现WebService

一、CXF简介 Apache CXF Celtix XFire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华&#xff0c;提供了对 JAX-WS 全面的支持&#xff0c;并且提供了多种 Binding …

SpringBoot2 整合 CXF 服务端和客户端

文章目录 一、CXF服务端1. 导入依赖2. 创建service接口3. 接口实现类4. cxf配置类5. 查看wsdl结果 二、CXF客户端2.1. 客户端2.2. 断点调试2.3. 发起调用服务开源源码. 一、CXF服务端 1. 导入依赖 <properties><cxf.version>3.3.1</cxf.version></proper…

CXF客户端乱码

CXF客户端乱码 解决办法一&#xff0c;设置服务端代码&#xff1a; 在使用CXF与其他系统对接时&#xff0c;发现对方系统响应的汉字乱码&#xff0c;使用soapui调用测试就没有问题&#xff0c;但是程序里面调用就乱码&#xff0c;很奇怪&#xff0c;乱码如下&#xff1a; 由…

SpringBoot集成CXF

CXF入门篇https://blog.csdn.net/tongxin_tongmeng/article/details/126482362Server端项目结构 Server端pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"…

走进cxf

一、什么是cxf 有很多人认为cxf就是webservice&#xff0c;其实cxf只是发布调用webservice的工具而已 Apache CXF Celtix Xfire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。Apache CXF 是一个开源的 web Service…

NewSQL ---- Mysql.8.0 与 MemSQL 7.0 大数据量查询性能对比

目录 1测试环境以及测试用例设计 1.1测试环境 1.2测试用例设计 2 千万级数据量性能测试对比 2.1 MemSQL时间范围分页查询 2.1.1 性能测试数据 2.2任务信息查询 2.2.1 性能测试数据 2.3 执行批次范围查询 2.3.1 性能测试数据 2.4 批次任务查询 2.4.1 性能测试数据 …

memsql架构2

接上次的MemSQL分布式架构介绍(一)&#xff0c;原文在这里&#xff1a;http://docs.memsql.com/latest/concepts/distributed_architecture/ 首先上张图&#xff0c;是我根据自己的理解画的&#xff0c;如有错误还请大家指出 几个概念 1、MemSQL有两种类型的表&#xff1a; ref…

MemSQL性能测试结果

1.查询的SQL select count(subie.user_id) as count from sum_user_basic_info_exp subie join sum_user_lend_info_exp sulie on sulie.user_idsubie.user_id where subie.curr_user_role_cd1 and subie.reg_dt >2016-08-29 and subie.reg_dt <2016-08-29 结…

【MySQL】SQL优化

SQL优化 1 插入数据 1.1 insert优化 如果我们需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化。 insert into tb_test values(1,tom); insert into tb_test values(2,cat); insert into tb_test values(3,jerry); .....1.批量插入数据 Insert…

MySQL慢SQL探究

文章目录 前言1、慢SQL捕获慢查询追踪配置方式 2、情况分析为什么查询会慢&#xff1f; 2.1 SQL执行计划分析explain执行计划分析PROFILE分析OPTIMIZER_TRACE分析 3、引擎参数配置分析I/O性能分析MySQL I/O参数 其他原因分析网络抖动单表数据量过大 总结 前言 我们在日常开发中…

【Mysql】SQL性能分析

【Mysql】SQL性能分析 文章目录 【Mysql】SQL性能分析1. SQL执行频率2. 慢查询日志3. profile详情4. explain 1. SQL执行频率 在控制台中通过命令 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的 insert,update,del…

MemSQL可以为时间序列应用做些什么

版权声明&#xff1a;本文由腾讯云数据库产品团队整理&#xff0c;页面原始内容来自于db weekly英文官网&#xff0c;若转载请注明出处。翻译目的在于传递更多全球最新数据库领域相关信息&#xff0c;并不意味着腾讯云数据库产品团队赞同其观点或证实其内容的真实性。如果其他媒…

MySQL-SQL优化

文章目录 一、插入数据1、insert2、大批量插入数据 二、主键优化&#xff08;1&#xff09;数据组织方式&#xff08;2&#xff09;页分裂&#xff08;3&#xff09;页合并&#xff08;4&#xff09;索引设计原则 三、order by优化四、group by优化五、limit优化六、count优化1…

每秒1.28万亿行,最快的分布式关系数据库MemSQL又破记录了!

众所周知&#xff0c;如果交互式响应时间小于四分之一秒&#xff0c;那么人们会获得令人难以置信的满意度。当你提供的响应时间下降到大约四分之一秒时&#xff0c;交互对用户而言是即时的。 但是&#xff0c;由于大数据集和并发需求&#xff0c;给所有客户提供的速度水平似乎…

速度最快的数据库---MEMSQL的安装与部署

1. 什么是MEMSQL 前Facebook工程师创办的MemSQL公司获500万美元投资。号称世界上最快的分布式关系型数据库&#xff0c;兼容MySQL但快30倍&#xff0c;能实现每秒150万次事务。原理是仅用内存并将SQL预编译为C。2012年12月14&#xff0c;MemSQL 1.8 发布&#xff0c;号称最快的…

memsql-官宣世界最快的内存关系型数据库安装部署

官网地址&#xff1a;https://www.memsql.com/ 获取到的license:BGNhZmY4YjViM2Y1OTRhOTdiOTNlNTE0NmU3MGJhN2NlAAAAAAAAAAAEAAAAAAAAAAwwNAIYJLLETZcXn8NHKfJAS/Iai5hUjzaCMQ5PAhht2vDZAS1q1a49DPsq5gMGKY9AI0wmaSkAAA 1&#xff0c;memsql官网介绍 MemSQL 是一个分布式关系数…

memSQL简介

前言 由前Facebook工程师创办的MemSQL&#xff0c;号称世界上最快的分布式关系型数据库&#xff0c;兼容MySQL但快30倍&#xff0c;能实现每秒150万次事务。原理是仅用内存并将SQL预编译为C。 MemSQL 提供免费的开发者版本&#xff08;数据限制32G&#xff09;和全功能试用版…

统一异常处理解决方案

&#x1f481; 作者&#xff1a;小瓦匠 &#x1f496; 欢迎关注我的个人公众号&#xff1a;小瓦匠学编程。微信号&#xff1a;xiaowajiangxbc &#x1f4e2; 本中涉及到的所有代码资源&#xff0c;可以在公众号中获取&#xff0c;关注并回复&#xff1a;源码下载 &#x1f449;…

SpringBoot统一异常处理详解

文章目录 一、概述1、统一异常处理介绍2、原理和目标 二、Assert(断言)1、概述2、Assert自定义实战2.1 自定义接口Assert2.2 自定义异常2.3 Enum整合2.4 实战检测 三、统一异常处理器1、异常处理器说明1.1 handleServletException1.2 handleBindException和handleValidExceptio…