码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 使用CXF调用WSDL(二)


    简介

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

     上文链接:

    使用CXF调用WSDL(一)

    上文回顾

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

    正文

    1. /**
    2. * 调用远程过程
    3. */
    4. public Object call(DTGMM1020GERP paramEntity) {
    5. Object result = null;
    6. log.info("[PO创建时]入参:{}",JSON.toJSONString(paramEntity,true));
    7. Map map = JSONObject.parseObject(JSON.toJSONString(paramEntity, SerializerFeature.WriteDateUseDateFormat), Map.class);
    8. Map wsdl = getWSDLContent();
    9. Client client = (Client) wsdl.get("client");
    10. List partInfos = (List) wsdl.get("messagePartInfo");
    11. QName qName = (QName) wsdl.get("qname");
    12. String clazzName = partInfos.get(0).getTypeClass().getName();
    13. try {
    14. Object requestParamObject = Thread.currentThread().getContextClassLoader().loadClass(clazzName).newInstance();
    15. requestParamObject = analysisParam(requestParamObject,map);
    16. log.info("请求参数:{}",JSON.toJSON(requestParamObject));
    17. result = client.invoke(qName, requestParamObject);
    18. log.info("响应结果:{}",JSON.toJSONString(result,true));
    19. } catch (Exception e) {
    20. e.printStackTrace();
    21. }
    22. return result;
    23. }

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

    1. private static Object analysisParam(Object req, Map map) throws InstantiationException, IllegalAccessException {
    2. Field[] fields = req.getClass().getDeclaredFields();
    3. for (Field field : fields) {
    4. field.setAccessible(true);
    5. boolean b = field.getGenericType() instanceof ParameterizedType;
    6. //如果是泛型并且是List类型
    7. if(b && field.getType() == List.class){
    8. List cParam = (List) map.get(field.getName());
    9. log.info("子对象参数:{}",cParam);
    10. if(CollectionUtils.isEmpty(cParam)){
    11. continue;
    12. }
    13. Type type = ((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0];
    14. Class aClass = (Class) type;
    15. Object cObj = aClass.newInstance();
    16. log.info("子对象:{}",cObj);
    17. Field[] cFields = cObj.getClass().getDeclaredFields();
    18. for (Field cField : cFields) {
    19. cField.setAccessible(true);
    20. List target = cParam.stream().map(o -> {
    21. Map ccParam = JSONObject.parseObject(JSON.toJSONString(o),Map.class);
    22. Object strParam = ccParam.get(cField.getName());
    23. //如果子对象类型是基本类型或String类型那就直接赋值,负责就递归
    24. if(cField.getType().isPrimitive() || cField.getType() == String.class){
    25. try {
    26. if(null != strParam){
    27. cField.set(cObj,strParam);
    28. }
    29. } catch (IllegalAccessException e) {
    30. throw new RuntimeException(e);
    31. }
    32. }else{
    33. try {
    34. Object obj = cField.getType().newInstance();
    35. Map objMap = JSONObject.parseObject(JSON.toJSONString(strParam),Map.class);
    36. if(!CollectionUtils.isEmpty(objMap)){
    37. analysisParam(obj,objMap);
    38. cField.set(cObj,obj);
    39. }
    40. } catch (InstantiationException e) {
    41. throw new RuntimeException(e);
    42. } catch (IllegalAccessException e) {
    43. throw new RuntimeException(e);
    44. }
    45. }
    46. return strParam;
    47. }).collect(Collectors.toList());
    48. /*Object targetResp = target.get(0);
    49. cField.set(cObj,targetResp);*/
    50. }
    51. List cObjs = new ArrayList<>();
    52. cObjs.add(cObj);
    53. //给父对象赋值
    54. field.set(req,cObjs);
    55. }else if(field.getType().isPrimitive() || field.getType() == String.class){
    56. //如果是基本类型或String类型
    57. field.set(req,map.get(field.getName()));
    58. }else{
    59. //按对象处理
    60. Object o = field.getType().newInstance();
    61. Map childrenObjMap = (Map) map.get(field.getName());
    62. if(!CollectionUtils.isEmpty(childrenObjMap)){
    63. writeFieldValue(o,childrenObjMap);
    64. field.set(req,o);
    65. }
    66. }
    67. }
    68. return req;
    69. }
    70.  步骤解析:

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

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

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

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

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

      使用CXF调用WSDL(一)

      完成


      文末

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

      1. public static T getEntityData(T t) {
      2. Field[] field = t.getClass().getDeclaredFields();
      3. for (Field f : field) {
      4. f.setAccessible(true);
      5. try {
      6. Random random = new Random();
      7. int num = random.nextInt(10);
      8. f.set(t,""+num);
      9. } catch (IllegalAccessException e) {
      10. throw new RuntimeException(e);
      11. }
      12. }
      13. return t;
      14. }

      用法

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

      1. List list = new ArrayList<>();
      2. DTGMM1020GERP entity = new DTGMM1020GERP();
      3. entity = getEntityData(entity);
      4. list.add(entity);

      结束

    71. 相关阅读:
      Arduino框架下ESP32/8266使用PROGMEM功能将数据存储到flash中的使用规范
      网络编程启蒙
      前端基础建设与架构18 对比 Koa 和 Redux:分析前端中的中间件理念
      第一个MyBatis程序
      Django 如何使用 Celery 完成异步任务或定时任务
      模型降阶方法之张量方法应用举例
      MySQL表的增查(进阶)
      PDO::fetchAll 与 PDO::fetch 循环
      【java学习—九】接口 interface(5)
      【区块链实战】什么是智能合约,如何搭建智能合约环境
    72. 原文地址:https://blog.csdn.net/cm777/article/details/134404726
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号