当前位置: 首页 > article >正文

使用CXF调用WSDL(二)

简介

本篇文章主要解决了上篇文章中遗留的对象嵌套问题,要想全面解析无限极的对象嵌套需要使用递归去解决

 上文链接:

使用CXF调用WSDL(一)

上文回顾

上文使用了单方法“ call() ”解决了List和基本类型(含String)以及对象的解析,但遗留了对象嵌套问题,本文将把 “ call() ” 方法中关于对象解析的部分拆分出独立的方法 “ analysisParam() ”,然后使用递归解决对象的嵌套问题

正文

    /**
     * 调用远程过程
     */
    public Object call(DTGMM1020GERP paramEntity) {
        Object result = null;
        log.info("[PO创建时]入参:{}",JSON.toJSONString(paramEntity,true));
        Map map = JSONObject.parseObject(JSON.toJSONString(paramEntity, SerializerFeature.WriteDateUseDateFormat), Map.class);
        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();
            requestParamObject = analysisParam(requestParamObject,map);
            log.info("请求参数:{}",JSON.toJSON(requestParamObject));
            result = client.invoke(qName, requestParamObject);
            log.info("响应结果:{}",JSON.toJSONString(result,true));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

解说:方法 “ call() ” 接收一个 “ DTGMM1020GERP ” 对象作为入参并返回一个Object对象,该方法主要业务就是将入参对象转换成map对象,而后读取WSDL文件内容,并传入给 “ analysisParam() ” 方法解析,其中requestParamObject是读出的WSDL文件的节点,map是待写入节点的值

private static Object analysisParam(Object req, Map map) throws InstantiationException, IllegalAccessException {
        Field[] fields = req.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            boolean b = field.getGenericType() instanceof ParameterizedType;
            //如果是泛型并且是List类型
            if(b && field.getType() == List.class){
                List<?> cParam = (List<?>) map.get(field.getName());
                log.info("子对象参数:{}",cParam);
                if(CollectionUtils.isEmpty(cParam)){
                    continue;
                }
                Type type = ((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0];
                Class<?> aClass = (Class<?>) type;
                Object cObj = aClass.newInstance();
                log.info("子对象:{}",cObj);

                Field[] cFields = cObj.getClass().getDeclaredFields();
                for (Field cField : cFields) {
                    cField.setAccessible(true);
                    List<?> target = cParam.stream().map(o -> {
                        Map ccParam = JSONObject.parseObject(JSON.toJSONString(o),Map.class);
                        Object strParam = ccParam.get(cField.getName());
                        //如果子对象类型是基本类型或String类型那就直接赋值,负责就递归
                        if(cField.getType().isPrimitive() || cField.getType() == String.class){
                            try {
                                if(null != strParam){
                                    cField.set(cObj,strParam);
                                }
                            } catch (IllegalAccessException e) {
                                throw new RuntimeException(e);
                            }
                        }else{
                            try {
                                Object obj = cField.getType().newInstance();
                                Map objMap = JSONObject.parseObject(JSON.toJSONString(strParam),Map.class);
                                if(!CollectionUtils.isEmpty(objMap)){
                                    analysisParam(obj,objMap);
                                    cField.set(cObj,obj);
                                }
                            } catch (InstantiationException e) {
                                throw new RuntimeException(e);
                            } catch (IllegalAccessException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        return strParam;
                    }).collect(Collectors.toList());
                    /*Object targetResp = target.get(0);
                    cField.set(cObj,targetResp);*/
                }
                List<Object> cObjs = new ArrayList<>();
                cObjs.add(cObj);
                //给父对象赋值
                field.set(req,cObjs);
            }else if(field.getType().isPrimitive() || field.getType() == String.class){
                //如果是基本类型或String类型
                field.set(req,map.get(field.getName()));
            }else{
                //按对象处理
                Object o = field.getType().newInstance();
                Map childrenObjMap = (Map) map.get(field.getName());
                if(!CollectionUtils.isEmpty(childrenObjMap)){
                    writeFieldValue(o,childrenObjMap);
                    field.set(req,o);
                }
            }
        }
        return req;
    }

 步骤解析:

一、使用反射获取待解析节点的字段

二、进行第一层 for 循环解析节点,先判断了字段的类型是否为泛型且为List类型,如果不是泛型且不是List类型,再判断是否为基本类型或是String类型,如果也不是,那就当成普通对象处理

三、如果第一层 for 循环中的类型为泛型且为List类型时,则进行第二层 for 循环处理,第二层循环同样判断子对象字段值是否为基本类型或String类型,如果是则直接赋值,如果不是,则说明是一个对象,至于是个什么对象(List?基本类型?String?POJO?),无需理会,直接进行递归解析即可

注意:map的key需和待解析的节点字段名保持一致,因为map.get()是通过field.getName()取值的

本文中引用到的其他方法请从上一篇文章中获取

使用CXF调用WSDL(一)

完成


文末

这是我mock加数据的方法,入参对象可以使用该方法快速生成mock数据(本文中的DTGMM1020GERP )

    public static <T> T getEntityData(T t) {
        Field[] field = t.getClass().getDeclaredFields();
        for (Field f : field) {
            f.setAccessible(true);
            try {
                Random random = new Random();
                int num = random.nextInt(10);
                f.set(t,""+num);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return t;
    }

用法

只需要定义好对象的嵌套层级即可 

List<DTGMM1020GERP> list = new ArrayList<>();
DTGMM1020GERP entity = new DTGMM1020GERP();
entity = getEntityData(entity);
list.add(entity);

结束


http://www.kler.cn/a/132723.html

相关文章:

  • 5. langgraph中的react agent使用 (从零构建一个react agent)
  • XXL-JOB相关面试题
  • OpenGL 进阶系列11 - 粒子特效(使用 Compute Shader)
  • 【MySQL】优化方向+表连接
  • 如何进入python交互界面
  • 红外遥控信号解码
  • ascii 码对照表
  • LeetCode704.二分查找及二分法
  • Filter和ThreadLocal结合存储用户id信息
  • 傅里叶分析(2)
  • elementui 实现树形控件单选
  • 哈希
  • 解决Redis分布式锁宕机出现不可靠问题-zookeeper分布式锁
  • kubernetes|云原生| 如何优雅的重启和更新pod---pod生命周期管理实务
  • QGIS003:【05高级数字化工具栏】-要素移动、修改、合并操作
  • Hadoop学习总结(MapRdeuce的词频统计)
  • 【原创】java+swing+mysql鲜花购物商城设计与实现
  • ATTCK实战系列——红队实战(一)
  • Alibaba Nacos注册中心源码剖析
  • 6.6.比例尺图层(ScaleBarOverlay)
  • Django框架之模型层(一)
  • 2023.11.17-hive调优的常见方式
  • nodeJs基础笔记
  • 自定义vtkActor动画场景及事件_vtkAnimationScene
  • Feature Pyramid Networks for Object Detection(2017.4)
  • [数据集][目标检测]斑马数据集VOC+yolo格式375张1类别