orika 工具下划线转驼峰不同字段名映射

news2024/11/27 4:23:27

1.问题:

业务需要把第三方接口的带下划线的字段规范为驼峰的字段
第三方接口的bean对象:

public class ObjectsDetail extends XMLElementData implements Serializable {
    private static final long serialVersionUID = 5080447582610246168L;
    private String objectclass;
    private String view_guid;
    private String group_guid;
    private String user_guid;
    private String all_path_name;
    private String original_sort;
 }

要转换为驼峰的本地对象

@Data
@NoArgsConstructor
@AllArgsConstructor
public class H4aUsers {
   
    private String objectclass;
  
    private String viewGuid;
 
    private String groupGuid;
  
    private String userGuid;
    
    private String allPathName;
  
    private String originalSort;
 }

2.解决思路

2.1 使用自带的BidirectionalConverter接口

发现只能同字段名称不同字段类型转换,像String转Date,list转String
参考博客http://www.lxiaoyu.com/p/283285

2.2 使用orika自带的field方法实现

传入一个map对象即可

    /**
     * Map a field in both directions
     * 
     * @param fieldNameA
     *            property name in type A
     * @param fieldNameB
     *            property name in type B
     * @return
     */
    public ClassMapBuilder<A, B> field(String fieldNameA, String fieldNameB) {
        return fieldMap(fieldNameA, fieldNameB).add();
    }

2.2.1 使用hutool的反射工具获取两个对象的所有字段

使用CharSequenceUtil.toCamelCase()方法把下划线转驼峰字段判断,然后映射到map集合返回

  public Map<String, String> getCamelCaseMap(Class<?> source, Class<?> des) {
        //带下划线的实体类字段集合
        Field[] sourceFields = ReflectUtil.getFields(source);
        log.info("getCamelCaseMap sourceFields = " + sourceFields.length);
        //带驼峰的实体类字段集合
        Field[] desFields = ReflectUtil.getFields(des);
        log.info("getCamelCaseMap desFields = " + desFields.length);
        //只获取字段名集合
        List<String> sources = Arrays.stream(sourceFields).map(Field::getName).collect(Collectors.toList());
        Map<String, String> fieldsMap = Maps.newHashMap();
        //遍历驼峰字段集合
        for (Field desField : desFields) {
            String name = desField.getName();
            //判断是否和转换后的字段相同
            Optional<String> first = sources.stream().filter(s -> Objects.equals(CharSequenceUtil.toCamelCase(s), name)).findFirst();
            //相同则放入map映射
            if (first.isPresent()) {
                fieldsMap.put(first.get(), name);
            }else {
                log.info("getCamelCaseMap name = " + name);
            }
        }
        log.info("getCamelCaseMap fieldsMap = " + fieldsMap.size());
        return fieldsMap;
    }

2.2.2 把获取的map传给orika

     /**
     * 获取自定义映射
     *
     * @param toClass       映射类
     * @param dataClass     数据映射类
     * @param configMap     自定义配置
     * @param useDefaultMap 是否使用默认映射
     * @return 映射类对象
     */
    private <E, T> MapperFacade getMapperFacade(Class<E> toClass, Class<T> dataClass, Map<String, String> configMap, List<CustomConverter<?, ?>> converter, boolean useDefaultMap) {
        String mapKey = dataClass.getCanonicalName() + "_" + toClass.getCanonicalName();
        MapperFacade mapperFacade = CACHE_MAPPER_FACADE_MAP.get(mapKey);
        if (Objects.isNull(mapperFacade)) {
            MapperFactory factory = new DefaultMapperFactory.Builder().build();
            if (!converter.isEmpty()) {
                converter.forEach(con -> factory.getConverterFactory().registerConverter(con));
            }
            ClassMapBuilder classMapBuilder = factory.classMap(dataClass, toClass);
            //映射不同字段名的实体
            if (CollUtil.isNotEmpty(configMap)) {
                configMap.forEach(classMapBuilder::field);
            }
            if (useDefaultMap) {
                classMapBuilder.byDefault();
            }
            classMapBuilder.register();
            mapperFacade = factory.getMapperFacade();
            CACHE_MAPPER_FACADE_MAP.put(mapKey, mapperFacade);
        }
        return mapperFacade;
    }
 /**
     * 映射实体(自定义配置)
     *
     * @param toClass   映射类对象
     * @param data      数据(对象)
     * @param configMap 自定义配置
     * @return 映射类对象
     */
    public <E, T> E map(Class<E> toClass, T data, Map<String, String> configMap) {
        MapperFacade mapperFacade = this.getMapperFacade(toClass, data.getClass(), configMap, new ArrayList<>(), true);
        return mapperFacade.map(data, toClass);
    }

2.2.3 测试

   @Test
    public void testCamlCase() {
        ObjectsDetail objectsDetail = new ObjectsDetail();
        objectsDetail.setOrg_class("1111");
        objectsDetail.setOrg_guid("2222");
        objectsDetail.setObjectclass("33333");
        objectsDetail.setView_guid("4444");
        objectsDetail.setUser_guid("5555");
        objectsDetail.setAll_path_name("666666");
        objectsDetail.setOriginal_sort("7777");


        Map<String, String> camelCaseMap = OrikaTool.getInstance().getCamelCaseMap(ObjectsDetail.class, H4aUsers.class);
        H4aUsers map = OrikaTool.getInstance().map(H4aUsers.class, objectsDetail, camelCaseMap);
        System.out.println("map = " + map);

    }

测试结果:

3.注意

转驼峰的实体一定要实现无参构造和有参构造,orika是根据构造方法获取参数去映射的

@Data
@NoArgsConstructor
@AllArgsConstructor
public class H4aUsers {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143290.html

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

相关文章

用300行Python代码实现一个人脸识别系统源码,基于dlib

用300行Python代码实现一个人脸识别系统 完整代码下载地址&#xff1a;用300行Python代码实现一个人脸识别系统源码&#xff0c;基于dlib 今天我们来python实现一个人脸识别系统&#xff0c;主要是借助了dlib这个库&#xff0c;相当于我们直接调用现成的库来进行人脸识别&…

科技云报道:“大建设”时期,AI算力何去何从?

科技云报道原创。 算力就是生产力&#xff0c;得算力者得天下。 随着新一代人工智能技术的快速发展和突破&#xff0c;以深度学习计算模式为主的AI算力需求呈指数级增长。 数据显示&#xff0c;在1960到2010年间&#xff0c;AI的计算复杂度每两年翻一番&#xff1b;在2010到2…

fastposter v2.11.0 天花板级的海报生成器

fastposter v2.11.0 天花板级的海报生成器 &#x1f525;&#x1f525;&#x1f525; fastposter海报生成器是一款快速开发海报的工具。只需上传一张背景图&#xff0c;在对应的位置放上组件&#xff08;文字、图片、二维&#x1f434;、头像&#xff09;即可生成海报。 点击代…

实验二十一 配置NAT

实验二十一 配置NAT实验要求&#xff1a; 静态NAT: 在Router的公网侧接口GE0/0/1下配置静态NAT&#xff0c;将私有 IP地址 192.168.0.2与公有IP地址202.10.1.3绑定起来。 NAT SERVER的配置 动态NAT和easy IP的配置网络拓扑图&#xff1a;操作步骤&#xff1a;一、静态NAT1、配置…

Actipro-wpf-controls-22.1.4 2023注册版

Actipro WPF 控件 用于构建漂亮的 Windows Presentation Foundation 桌面应用程序的大量 UI 控件 特征 超过 100 个 WPF 控件和组件在各种产品中可用&#xff0c;Ω578867473它们通过丰富的特性和功能改进应用程序的 UI。 受办公室启发的用户界面 复制现代 Office 应用程序的外…

【数据结构】计数排序、基数排序

文章目录计数排序基数排序计数排序 计数排序也是非比较排序的一种&#xff0c;在之前的博客介绍的都是比较排序&#xff0c;跟之前的比较排序相比计数排序并不是很常用&#xff0c;不常用的原因也是它的局限性耗费空间很大&#xff0c;只能对整数进行排序&#xff0c;并且数据在…

【验证码逆向专栏】某验四代滑块验证码逆向分析

文章目录声明逆向目标通讯流程验证码流程分析逆向分析captcha_id 参数challenge 参数w 参数结果验证声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与…

剑指 Offer 27. 二叉树的镜像(Leetcode 226. 翻转二叉树)(二叉树后序遍历)

题目&#xff1a; 链接&#xff1a;剑指 Offer 27. 二叉树的镜像&#xff1b;Leetcode 226. 翻转二叉树 难度&#xff1a;简单 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,…

调用Ishingami Homma解析函数测试PAWN算法(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 灵敏度分析分为局部灵敏度分析和全局灵敏度分析&#xff1b;局部灵敏度分析包括&#xff1a;直接求导法、有限差分法、格林函数…

06-07-Alibaba Nacos注册中心源码剖析

Nacos&Ribbon&Feign核心微服务架构图 架构原理 1、微服务系统在启动时将自己注册到服务注册中心&#xff0c;同时外发布 Http 接口供其它系统调用(一般都是基于SpringMVC) 2、服务消费者基于 Feign 调用服务提供者对外发布的接口&#xff0c;先对调用的本地接口加上注…

Github每日精选(第85期):PDF 文档的 React 组件react-pdf-viewer

react-pdf-viewer react-pdf-viewer 用于查看 PDF 文档的 React 组件。它是用 TypeScript 编写的&#xff0c;完全由 React hooks 提供支持。 github 的地址在这里。 使用实例 添加水印 默认情况下&#xff0c;每个页面由画布、文本和注释层构成。在此示例中&#xff0c;我…

RCE(命令执行)总结

文章目录RCE(命令、代码执行)总结1、过滤cat、flag等关键字1.1 常见linux系统命令1.2 使用转义符1.3 使用引号1.4 内联执行绕过1.5 编码绕过1.6 进制绕过1.7 过滤文件名(如&#xff1a; /etc/passwd文件)1.8 使用$*和$&#xff0c;$x,${x}1.9 读取文件命令1.10 查找文件命令(fi…

【观察】汇聚中国开源数据库创新力量,openGauss驶入发展“快车道”

毫无疑问&#xff0c;数据库是“软件产业皇冠上的明珠”&#xff0c;是数字基础设施不可或缺的底座之一。但也要看到&#xff0c;由于数据库难度大&#xff0c;产业投入周期长&#xff0c;迫切需要凝聚产业力量共建基础能力。在此背景之下&#xff0c;作为定位企业级开源数据库…

H264 NALU分析以及提取h264实战

1.H264简介 H.264从1999年开始&#xff0c;到2003年形成草案&#xff0c;最后在2007年定稿有待核实。在ITU的标准⾥称 为H.264&#xff0c;在MPEG的标准⾥是MPEG-4的⼀个组成部分–MPEG-4 Part 10&#xff0c;⼜叫Advanced Video Codec&#xff0c;因此常常称为MPEG-4 AVC或直…

Java学习(22)调试初步——debug入门

程序调试-debug 调试的作用 让程序员能看清程序每一步的效果&#xff0c;在需要查看结果的时候&#xff0c;使用debug查看实际结果是否与预期结果一致。案例 (1) 设置断点 鼠标左键双击设置/取消&#xff0c;或者右键选择Toggle Breakpoint。 (2) 执行调试 Run→\to→Debug&a…

快速了解chrony服务器

目录 一、chrony服务器 二、chrony安装与配置 三、时间服务器 四、配置时间服务器 一、chrony服务器 Chrony是一个开源自由的网络时间协议 NTP 的客户端和服务器软软件。它能让计算机保持系统时钟与时钟服务器&#xff08;NTP&#xff09;同步&#xff0c;因此让你的计算机…

操作系统期末复习题-不挂科

写在前面&#xff1a; 本题目由博主收集而成&#xff0c;如有侵权请告知删除&#xff01; 一、选择题 DMA 控制方式是在&#xff08; B&#xff09;之间建立一条直接数据通路。 A. I/O 设备与 CPU B. I/O 设备与主存 C. CPU 与主存 D. I/O 设备之间 以下 I/O 控制方式中&…

javaee之springMVC3

ssm整合说明 ssm整合之搭建环境 现在先去数据里面&#xff0c;创建好库&#xff0c;创建好表 然后在pom.xml中引入各种需要的jar包 pom.xml <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0"…

webpack起步

webpack 1&#xff0c;起步 先安装node.js 再用npm安装webpack全局 运用commonjs模块化语法&#xff0c;用全局命令进行打包来初步了解一下 命令为&#xff1a; webpack 入口main路径 出口bundle路径 很麻烦所以要配置一下webpack入口出口配置。 2&#xff0c;配置 webpa…