首页 > 其他分享 >[JSON|序列化] fastjson自定义字段命名规则 (转发)

[JSON|序列化] fastjson自定义字段命名规则 (转发)

时间:2023-09-27 12:56:00浏览次数:38  
标签:fastjson userName name 自定义 JSON 序列化 属性

1 序言

  • 博主本人近期也遇到了 基于 fatsjson 自定义命名字段规则的问题,为加强对此的学习和记忆,故转发这篇博文。
  • 博主本人最终采取的方法2

1.1 前置知识

  • fastjson 在将对象转变为 JSON 字符串时,字段默认使用 CamelCase 规则命名。

  • 在1.2.15版本之后,fastjson 支持配置 PropertyNamingStrategy,支持四种策略:

    • CamelCase
    • PascalCase
    • SnakeCase
    • KebabCase
  • 属性名策略说明:

    • CamelCase策略,Java对象属性:userName,序列化后属性:userName;
    • PascalCase策略,Java对象属性:userName,序列化后属性:UserName;
    • SnakeCase策略,Java对象属性:userName,序列化后属性:user_name;
    • KebabCase策略,Java对象属性:userName,序列化后属性:user-name;

1.2我的问题

公司规定 ElasticSearch 上索引的键需要使用大写字母表示,比如 USER_NAME,所以现在的规则没办法满足我的要求。

一开始想看一下是否可以实现什么接口来达到目的,但是发现 PropertyNamingStrategy 是个枚举类,无法继承。

2 FastJson 自定义字段命名规则

2.1 解决方法1: Object => Bean Map Object => upper(list fields)

将对象转变为 BeanMap 对象,遍历所有的字段,将字段转变为下划线大写的形式。

关键代码如下

import org.springframework.cglib.beans.BeanMap;

/**
 * 将对象转变为以字段为键,字段值为值的哈希表,并且字段名变为下划线大写的形式
 */
public static <T> Map<String, Object> beanToMap(T bean) {
    Map<String, Object> map = Maps.newHashMap();
    if (bean != null) {
        BeanMap beanMap = BeanMap.create(bean);
        for (Object key : beanMap.keySet()) {
            map.put(StrUtil.camelToUnderscore(key.toString()), beanMap.get(key));
        }
    }
    return map;
}

/**
 * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
 * 例如:HelloWorld->HELLO_WORLD
 *
 * @param name 转换前的驼峰式命名的字符串
 * @return 转换后下划线大写方式命名的字符串
 */
public static String camelToUnderscore(String name) {
    StringBuilder result = new StringBuilder();
    if (name != null && name.length() > 0) {
        // 将第一个字符处理成大写
        result.append(name.substring(0, 1).toUpperCase());
        // 循环处理其余字符
        for (int i = 1; i < name.length(); i++) {
            String s = name.substring(i, i + 1);
            // 在大写字母前添加下划线
            if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                result.append("_");
            }
            // 其他字符直接转成大写
            result.append(s.toUpperCase());
        }
    }
    return result.toString();
}

最后通过下面的代码可以将对象发送到 es 进行保存。

IndexRequest request = new IndexRequest(esIndex);
String infoId = StringUtil.toString(t.getInfoId());
request.routing(infoId).source(BeanMapUtil.beanToEsMap(t)).id(infoId);

2.2 解决方法2:@JsonField(name)

使用 @JsonField 的 name 属性,在 name 中直接指定命名规则,可以直接得到想要的 JSON 字符串。

示例如下

/**
 * @author linjinjia
 * @date 2021/8/23 20:09
 */
public class FastJsonTest {

    public static void main(String[] args) {
        System.out.println(JSON.toJSONString(new User("lin2j", 24)));
        User user = JSON.parseObject("{\"AGE\":24,\"USER_NAME\":\"lin2j\"}", User.class);
        System.out.println(user);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class User {
        @JSONField(name = "USER_NAME")
        private String userName;

        @JSONField(name = "AGE")
        private Integer age;
    }
}

demo output

{"AGE":24,"USER_NAME":"lin2j"}
FastJsonTest.User(userName=lin2j, age=24)

小结

但是方法一并不是通过 fastjson 来实现目的的,也会显得麻烦一些。
个人比较喜欢使用方法二,因为不用写那么多工具类。

X 参考文献

https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn

https://github.com/FasterXML/jackson/wiki/Jackson-Releases

标签:fastjson,userName,name,自定义,JSON,序列化,属性
From: https://www.cnblogs.com/johnnyzen/p/17732445.html

相关文章

  • 自动化测试中自定义断言的实现方法
    断言定义熟悉单元测试的同学都知道在测试用例中,执行完测试用例后,通过断言(assert)判断测试结果是pass还是fail。不同的单元测试框架都提供了断言机制,我们这里以python为例进行说明。Python中的断言类型丰富,最常用的是基础断言和集合断言。基础断言包括的核心方法如下所示,主要功能是对......
  • OpenHarmony装饰指定自定义组件:@BuilderParam装饰器
     当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,开......
  • 自定义Zabbix监控
    自定义Zabbix监控项1.为什么要自定义监控项模板里面提供了大量的监控项,为何还要自定义?那肯定是有些你想监控的内容,模板里没有当然,zabbix支持你自定义的监控项,所以才那么流行!2.自定义监控项流程1.自定义监控项的表现形式是(命令、脚本),只要能获取到值,就可以通过zabbix展示完......
  • SpringBoot | Redis序列化与分布式锁
    欢迎参观我的博客,一个Vue与SpringBoot结合的产物:https://poetize.cn博客:https://gitee.com/littledokey/poetize-vue2.git聊天室:https://gitee.com/littledokey/poetize-im-vue3.git后端:https://gitee.com/littledokey/poetize.git七牛云登录/注册地址(文件服务器,CDN):https:/......
  • SpringBoot | Jackson序列化
    欢迎参观我的博客,一个Vue与SpringBoot结合的产物:https://poetize.cn博客:https://gitee.com/littledokey/poetize-vue2.git聊天室:https://gitee.com/littledokey/poetize-im-vue3.git后端:https://gitee.com/littledokey/poetize.git七牛云登录/注册地址(文件服务器,CDN):https:/......
  • qt自定义实体类
    在Qt中,可以创建自己的实体类(EntityClass)来表示应用程序中的数据对象或模型。这些实体类通常用于表示数据、管理数据和进行数据操作。以下是创建Qt自定义实体类的一般步骤:创建一个新的C++类:使用QtCreator或您喜欢的C++集成开发环境,创建一个新的C++类来表示实体。可以选择从QObject......
  • 使用vite插件进行低代码平台自定义开发(手机版自定义范例)
    前言Youtube上的前端网红「Theo」在React文档仓库发起了一个Pullrequest,号召React文档不要再默认推荐CRA(createreactapp),而是应该将Vite作为构建应用的首选。vite的影响力已经从vue蔓延到了react,可见在前端工程化开发中,它已经越来越流行,是时候该从webpack切换到vite了。为什么......
  • 使用vite插件进行低代码平台自定义开发(手机版自定义范例)
    前言Youtube上的前端网红「Theo」在React文档仓库发起了一个Pullrequest,号召React文档不要再默认推荐CRA(createreactapp),而是应该将Vite作为构建应用的首选。vite的影响力已经从vue蔓延到了react,可见在前端工程化开发中,它已经越来越流行,是时候该从webpack切换到vite了。为......
  • 185_技巧_Power Query(M)语言快捷输入之搜狗输入法设置自定义短语
    185_技巧_PowerQuery(M)语言快捷输入之搜狗输入法设置自定义短语此前,我们发布过如何通过QQ拼音输入法来实现快速的输入PowerQuery(M)语言。参考:https://jiaopengzi.com/730.html今天我们来更新PowerQuery(M)语言在搜狗输入法中设置自定义短语的快捷输入。快捷输入效......
  • 浅谈UE4的序列化
    【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!一、结合用例浅谈UE4序列化1.1需求我写文章,不爱一上来就讲道理、贴代码,而是喜欢先提需求、提问题,然后围绕这个需求的实现再一步步挖掘源码。我们......