JSON字符串转JSON, 字段名不一致

前言

不 知 道 你 有 没 有 遇 到 j s o n 字 符 串 转 对 象 , 字 段 需 要 从 下 划 线 转 驼 峰 命 名 问 题 ? \color{red}不知道你有没有遇到json字符串转对象,字段需要从下划线转驼峰命名问题? json线
不 知 道 你 有 没 有 遇 到 j s o n 字 符 串 转 对 象 , 字 段 名 和 对 象 属 性 字 段 对 不 上 问 题 ? \color{red}不知道你有没有遇到json字符串转对象,字段名和对象属性字段对不上问题? json
最 近 刚 好 遇 到 这 两 类 问 题 , 记 录 一 下 , 希 望 对 你 有 帮 助 \color{red}最近刚好遇到这两类问题,记录一下,希望对你有帮助

默认情况下支持 下划线转驼峰命名

JSONObject.parseObject(str, Merchandise.class);
实体类1:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;


/**
 * @description:
 * @author: hongbin.zheng
 * @create: 2021-09-23 16:04
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Merchandise {
    private Integer id;
    private Long merItemNo;
    private Long merchandiseNo;
    private String goodsName;
    private Date startTime;
    private String aB;
    private String aBC;

}

测试类:

@Test
    public void test2() {
        String str = "{\"id\":1,\"mer_item_no\":10010001,\"merchandiseNo\":1001,\"goods_name\":\"其他备注信息\", start_time: \"2021-09-23T01:13:47.751Z\"" +
                ", aB:\"123\", aBC:\"123456789\"}";
        Merchandise merchandise = JSONObject.parseObject(str, Merchandise.class);
        System.out.println(merchandise.toString());
    }

在这里插入图片描述

使用@JsonField注解,解决字段名不符合问题

案例

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

import java.util.List;

/**
 * FileName: InsideCaliberMsg
 */
@Data
public class OpponPricePoolMsg {
    @JSONField(name = "a_b_c")
    private Long merchandiseNo;

    @JSONField(name = "d")
    private Byte dimension;

    private Byte reUpdate;

    private Byte pe_update;

    /**
     * matchId集合
     */

    private List<Long> matchIds;
}

测试类


  @Test
    public void test() {
        String str = "{\n" +
                " \"a_b_c\":1008611,\n" +
                " \"d\": 1,\n" +
                " \"re_update\": 1,\n" +
                " \"pe_update\":1,\n" +
                " \"matchIds\":[1,2,3]\n" +
                "}";
        OpponPricePoolMsg opponPricePoolMsg = JSONObject.parseObject(str, OpponPricePoolMsg.class);
        System.out.println(opponPricePoolMsg);
    }

在这里插入图片描述

自定义解析的方法

题目:假设json字符串分隔符为^,在ASCII编码为94
在这里插入图片描述
提供工具类解析

package com.dgut.edu.cn.testxiaozheng.utils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
import com.google.common.collect.Maps;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.StringUtils;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description:
 * @author: hongbin.zheng
 * @create: 2021-09-24 10:11
 **/
public class ReceivingDataWorkshopUtil {
    private ReceivingDataWorkshopUtil(){};

    private static DeserializerFilter deserializerFilter = new DeserializerFilter();


    public static <T> T receiving(String msg,Class<T> clazz){
        ReceivingMsg messages = JSONObject.parseObject(msg, ReceivingMsg.class, deserializerFilter);
        BeanWrapperImpl bw = new BeanWrapperImpl(clazz);
        for (Map.Entry<String, Object> entry : messages.getMap().entrySet()) {
            String entityFieldName = entry.getKey();
            if (bw.isWritableProperty(entityFieldName)) {
                bw.setPropertyValue(entityFieldName, entry.getValue());
            }
        }
        return (T)bw.getWrappedInstance();
    }

    private static class ReceivingMsg {
        private Map<String, Object> map = Maps.newHashMap();

        public Map<String, Object> getMap() {
            return map;
        }
    }

    private static class DeserializerFilter implements ExtraProcessor, ExtraTypeProvider {

        private static ConcurrentHashMap<String,String> fieldMap = new ConcurrentHashMap<>();

        /**
         * 全部放入map中
         * @param o
         * @param key
         * @param value
         */
        @Override
        public void processExtra(Object o, String key, Object value) {
            ReceivingMsg msg = (ReceivingMsg) o;
            if (key.contains("^")) {
                key = fieldMap.computeIfAbsent(key, this::toCamelCase);
            }
            msg.getMap().put(key, value);
        }

        /**
         * 如果是time或者date结尾的key,就告诉fastjson这个是date类型的字段
         * @param o
         * @param key
         * @return
         */
        @Override
        public Type getExtraType(Object o, String key) {
            if (StringUtils.endsWithIgnoreCase(key, "time") || StringUtils.endsWithIgnoreCase(key, "date")) {
                return Date.class;
            }
            return null;
        }

        private String toCamelCase(String underlineStr) {
            if (underlineStr == null) {
                return null;
            }
            // 分成数组
            char[] charArray = underlineStr.toCharArray();
            // 判断上次循环的字符是否是"_"
            boolean underlineBefore = false;
            StringBuilder buffer = new StringBuilder();
            for (int i = 0, l = charArray.length; i < l; i++) {
                // 判断当前字符是否是"_",如果跳出本次循环
                if (charArray[i] == 94) {
                    underlineBefore = true;
                } else if (underlineBefore) {
                    // 如果为true,代表上次的字符是"_",当前字符需要转成大写
                    buffer.append(charArray[i] -= 32);
                    underlineBefore = false;
                } else {
                    // 不是"_"后的字符就直接追加
                    buffer.append(charArray[i]);
                }
            }
            return buffer.toString();
        }
    }

}

测试类

 @Test
    public void test3() {
        String str = "{\"id\":1,\"mer^item^no\":10010001,\"merchandise^no\":1001,\"goods^name\":\"其他备注信息\", start_time: \"2021-09-23T01:13:47.751Z\"" +
                ", aB:\"123\", aBC:\"123456789\"}";
        Merchandise receiving = ReceivingDataWorkshopUtil.receiving(str, Merchandise.class);
        System.out.println(receiving);
    }

在这里插入图片描述

小总结

知 道 的 越 多 , 不 知 道 的 越 多 , 希 望 对 你 有 帮 助 ! 连 更 中 \color{red}知道的越多,不知道的越多,希望对你有帮助!连更中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值