使用CXF调用WSDL

news2024/11/26 12:31:53

简介

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

步骤一 :添加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://www.coloradmin.cn/o/471606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

( 字符串) 242. 有效的字母异位词 ——【Leetcode每日一题】

❓242. 有效的字母异位词 难度&#xff1a;简单 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s “anagram”, t “…

【5天打卡】学习Lodash的第五天——总结篇

Lodash 含有 Array, Collection, Date, Function, Lang, Math, Number, Object, String 等多个功能模块&#xff0c;总共几百个功能函数。官方文档上以字典顺序排序&#xff0c;不容易总结记忆。通过这5天的学习&#xff0c;我们对这一框架进行总结。主要从lodash的使用优势和迷…

电磁波、射频通信基础知识科普,超通俗解释!

一、电磁波 电磁波是能量的一种&#xff0c;凡是高于绝对零度的物体&#xff0c;都会释出电磁波。电与磁可说是一体两面&#xff0c;电流会产生磁场&#xff0c;变动的磁场则会产生电流。变化的电场和变化的磁场构成了一个不可分离的统一的场。 在低频的电振荡中&#xff0c;…

XCTF-Web2

Web_php_include <?php show_source(__FILE__); echo $_GET[hello]; $page$_GET[page]; while (strstr($page, "php://")) {$pagestr_replace("php://", "", $page); } include($page); ?>strstr() 查找字符串首次出现的位置&#xff0…

集合-ArrayList学习

1、特点&#xff1a; ArrayList 实现是一个动态数组&#xff0c;初始时是一个空数组。ArrayList 默认初始长度为0&#xff0c;在插入第一个元素的时候扩容为10&#xff0c;然后当数组存满的时候&#xff0c;数组会再次扩容&#xff0c;此时就扩容到原来的1.5倍。ArrayList 是线…

打造一个基于低代码的无代码平台,愿满足非专业人士的需求

一、开源项目简介 摸鱼低代码平台希望打造一个基于低代码的无代码平台。即能给程序员使用&#xff0c;也能满足非专业人士的需求。 后端基于Spring Cloud Alibaba注册中心、配置中心采用nacos当前版本完成oauth2统一认证接入持续进行功能完善 二、开源协议 使用Apache-2.0开…

人机交互到艺术设计及玫瑰花绘制实例

Python库之图形用户界面 Riverbank Computing | Introduction Welcome to wxPython! | wxPython Overview — PyGObject Python库之游戏开发 https://www.pygame.org/news Panda3D | Open Source Framework for 3D Rendering & Games python.cocos2d.org Python库之…

MATLAB科研数据可视化

互联网的飞速发展伴随着海量信息的产生&#xff0c;而海量信息的背后对应的则是海量数据。如何从这些海量数据中获取有价值的信息来供人们学习和工作使用&#xff0c;这就不得不用到大数据挖掘和分析技术。数据可视化分析作为大数据技术的核心一环&#xff0c;其重要性不言而喻…

scss、css样式中使用变量的方法;Vue动态改变css等样式文件中的变量

目录 一、问题 二、原因及解决方法 三、总结 一、问题 1.遇到一些样式 设置的值都是重复的不想重复写&#xff0c;想和js一样定义一个常量&#xff0c;然后直接引用这个常量。 2.想要在js中动态设置样式中的值&#xff0c;在 css、scss等样式表中直接使用。 二、原因及解…

nacos实战

spring cloud是一系列框架的有序集合&#xff0c;是分布式系统构建工具 服务领域模型 不同的组&#xff08;group&#xff09;之间不能调用&#xff0c;只能进行组内调用 namespace》group/service》cluster》instance 没有nacos的时候 微服务调用&#xff0c;可以直接使用Re…

React18开发总结(完善中)

遇到这样一个问题&#xff0c;初始化时用户登陆后需要获取到用户信息&#xff0c;但是发现获取用户信息这个接口触发了2次&#xff0c;这是不应该的&#xff0c;于是我查阅了一下资料&#xff0c;把自己的笔记记录下来。 还有就是使用mobx遇到的控制台警告问题&#xff0c;也一…

Python 中如何实现自动导入缺失的库?

在编写 Python 项目的时候&#xff0c;我们经常会遇到导入模块失败的错误&#xff1a; ImportError: No module named xxx或者ModuleNotFoundError: No module named xxx 导入失败&#xff0c;通常分为两种&#xff1a;一种是导入自己写的模块&#xff08;即以 .py 为后缀的文件…

你不想成长,生活总会逼着你成长,阿里P8架构师分享十年学习生涯

成为阿里P8&#xff0c;并不是一件容易的事情&#xff0c;我花了将近十年的时间&#xff0c;才达到了这样的目标。这十年间来&#xff0c;说辛苦也是真辛苦&#xff0c;但这些辛苦是让我感觉到满足的&#xff0c;毕竟这样的成功并不是人人都能够得来的。 为了成为阿里P8的这十…

Linux(ubuntu) 挂载磁盘

前言 很多博客写了一些格式化磁盘&#xff0c;分区等等&#xff0c;这和挂载磁盘的概念是混淆的。分区是为了安装系统&#xff0c;我们挂载磁盘肯定是已经安装好Ubuntu 系统了&#xff0c;分区干什么&#xff0c;误人子弟啊。 另外格式化磁盘并不是挂载磁盘必须的选项&#x…

55.网页设计规则#3_图片和插图

使用好的图片 图片类型 不同类型的图像&#xff1a;产品照片、故事性照片、插图、图案&#xff1b;使用图片来支持你网站的信息和故事。所以只使用相关的图片倾向于使用原始图片。如果不可能&#xff0c;请使用原始外观的图片&#xff08;而不是一般的图片&#xff01;&#…

Numpy方法总简单说明作用

NumPy的大部分代码都是用C语言写的&#xff0c;其底层算法在设计时就有着优异的性能&#xff0c;这使得NumPy比纯Python代码高效得多 NumPy&#xff08;Numerical Python&#xff09;是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵&#xff0c;比Python…

JAVAWeb10-Web 开发会话技术-Session-02

1. session 有什么用 ● 思考两个问题—抛砖引玉 不同的用户登录网站后&#xff0c;不管该用户浏览该网站的哪个页面&#xff0c;都可显示登录人的名字&#xff0c;还可以随时去查看自己的购物车中的商品, 是如何实现的?也就是说&#xff0c;一个用户在浏览网站不同页面时&a…

如何高效的学习接口自动化测试?从零开始学习接口自动化测试:选择合适的学习资源和编程语言

目录 引言&#xff1a; 一、学习前的准备 二、选择合适的学习资源 三、实践中学习 四、总结 引言&#xff1a; 在日常的软件开发过程中&#xff0c;接口自动化测试是一个非常重要的环节。接口自动化测试可以帮助我们快速准确地检测出软件中的缺陷&#xff0c;提高软件的质…

更简单的存取Bean方式-@Bean方法注解

1.Bean方法存储 类注解是添加在某个类上的,那么方法注解是添加在某个方法前的 public class UserBeans {Beanpublic User user1(){User user new User();user.setUid(001);user.setUname("zhangsan");user.setAge(19);user.setPassword("123123");retur…

Git/Github操作手册

Git 是目前最流行的版本管理工具&#xff0c;也是程序员的必备技能之一。 这里主要介绍一下git/github远程仓库的使用及相关配置&#xff1a; 一、SSH Keys SSH Keys是什么呢&#xff1f;简单来说相当于一把钥匙&#xff08;在机器中即电脑中进行配置&#xff09;&#xff0…