jackson版嵌套Json转Bean

jackson版嵌套Json转Bean

因为在网上找不到Jackson版的嵌套Json转Bean的方法,虽然Gson有这个功能,但是不想项目导入太多依赖包,所以就自己写了一套,可能会有bug,后期优化。٩(*Ӧ)و

package com.taiyang.test;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taiyang.test.entity.EnterpriseBetchCustomerInfoBO;
import com.taiyang.test.entity.Father;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: zhoutaiyang
 * @Desctription: jackson测试
 * @Date: Created in 2021/5/20 10:30
 * @Version: 1.0
 */
public class T01_JacksonTest {

    private static final List<String> arrayTypeName = Arrays.asList("Byte", "Short", "Integer", "Long", "Float", "Double", "Boolean", "String", "Character");
    private static ObjectMapper mapper = new ObjectMapper();

    public static void main(String[] args) {
        String json = "{\"errcode\":0,\"errmsg\":\"ok\",\"external_contact_list\":[{\"follow_info\":{\"userid\":\"ShenLe\",\"remark\":\"等等\",\"description\":\"\",\"createtime\":1619681978,\"tag_id\":[],\"remark_mobiles\":[],\"add_way\":1,\"oper_userid\":\"wmH4CnDAAAgK_8Cz6uL0dy0ig\"},\"external_contact\":{\"external_userid\":\"wmH4CnD_84jqmjzrCz6uL0dy0ig\",\"name\":\"等等\",\"type\":1,\"avatar\":\"http://wx.qlogo.cn/mmhead/Q3auHgzwzM6ysYneibnEmS1SOld08ZTIaohtEyX2t5g/0\",\"gender\":2,\"unionid\":\"oAoX152biNlpXaPJEVDcjOg\"}},{\"follow_info\":{\"userid\":\"ShenLe\",\"remark\":\"猪八戒\",\"description\":\"\",\"createtime\":1610695931,\"tag_id\":[],\"remark_mobiles\":[213123123],\"add_way\":1,\"oper_userid\":\"ShenLe\"},\"external_contact\":{\"external_userid\":\"wmH4CnDAAAH7HmN1uav7dg\",\"name\":\"猪八戒\",\"type\":1,\"avatar\":\"http://wx.qlogo.cn/mmhead/V0mh6n2lR6iawcrtVuHhOdDAnkpviq8F17XjBAGMInQ/0\",\"gender\":1,\"unionid\":\"oAoX15zp-mRnzvAkbO8vI\"}},{\"follow_info\":{\"userid\":\"ShenLe\",\"remark\":\"黑猫警长\",\"description\":\"\",\"createtime\":1610617428,\"tag_id\":[],\"remark_mobiles\":[],\"add_way\":3,\"oper_userid\":\"wmHAHlsVYQLpBXC2DQtPiENTjg\"},\"external_contact\":{\"external_userid\":\"wmH4CnDAAAHlsVYQLpBXC2DQtPiENTjg\",\"name\":\"黑猫警长\",\"type\":1,\"avatar\":\"http://wx.qlogo.cn/mm/r1UtgK7ROtjV6PVQzyHiaUCfLpvB1pJKKfBOPXLs/0\",\"gender\":1,\"unionid\":\"oAoX157ku355n06erL8Dqxcw\"}}],\"next_cursor\":\"\"}";
        try {
            EnterpriseBetchCustomerInfoBO betchCustomerInfoBO = new EnterpriseBetchCustomerInfoBO();
            // 转换为Bean
            convertToBean(betchCustomerInfoBO, json);
            System.out.println(betchCustomerInfoBO);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String testJson = "{\"name\":\"tom\",\"age\":28,\"sonList\":[{\"name\":\"tom child1\",\"age\":1,\"toyList\":[{\"name\":\"plane\"},{\"name\":\"car\"}],\"steps\":10},{\"name\":\"tom child2\",\"age\":2,\"toyList\":[{\"name\":\"car\"}],\"steps\":100},{\"name\":\"tom child3\",\"age\":3,\"toyList\":[{\"name\":\"plane\"}],\"steps\":1000}],\"steps\":99999}";
        Father father = new Father();
        try {
            convertToBean(father,testJson);
            System.out.println(father);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * jackson解析嵌套JSON
     *
     * @param o    实例化对象
     * @param json 要反序列化的json
     * @throws Exception
     */
    public static void convertToBean(Object o, String json) throws Exception {
        // 解析json为JsonNode
        JsonNode jsonNode = mapper.readTree(json);
        // bean内省,获得bean的信息和read method以及write method
        BeanInfo beanInfo = Introspector.getBeanInfo(o.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            Method writeMethod = propertyDescriptor.getWriteMethod();
            // 驼峰转下划线
            String upperCase = upperCaseToUnderline(propertyDescriptor.getName());
            // 不用驼峰
//            String upperCase = propertyDescriptor.getName();
            System.out.println(upperCase);
            // 获得json中的变量
            JsonNode jsonNodeValue = jsonNode.get(upperCase);
            if (jsonNodeValue == null) {
                continue;
            }
            // 是否是集合,未属性为数组的情况
            if (jsonNodeValue.isArray()) {
                Object arrayTypeObject = getClassInstance(writeMethod, true);
                // 属性是基本数据类型集合
                if (arrayTypeName.contains(arrayTypeObject.getClass().getSimpleName())) {
                    convert(writeMethod, o, jsonNodeValue);
                } else {
                    // 属性是对象集合
                    List<Object> objects = new ArrayList<>();
                    jsonNodeValue.elements().forEachRemaining(item -> {
                        try {
                            Object objectFiled = getClassInstance(writeMethod, true);
                            // 属性是对象集合,进行递归
                            convertToBean(objectFiled, item.toString());
                            objects.add(objectFiled);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                    writeMethod.invoke(o, objects);
                }
                continue;
            }
            // 为bean赋值
            convert(writeMethod, o, jsonNodeValue);
        }
    }

    /**
     * 类型转换
     */
    public static Object convert(Method writeMethod, Object object, JsonNode jsonNode) throws Exception {
        if (jsonNode == null) {
            return null;
        }
        Object objectFiled = null;
        Object result = null;
        switch (jsonNode.getNodeType()) {
            case NUMBER:
                String numTypeName = getTypeName(writeMethod.getParameterTypes()[0]);
                Object num = convertToTargetType(numTypeName, jsonNode.toString());
                result = writeMethod.invoke(object, num);
                break;
            case STRING:
                result = writeMethod.invoke(object, jsonNode.textValue());
                break;
            case BOOLEAN:
                result = writeMethod.invoke(object, jsonNode.booleanValue());
                break;
            case OBJECT:
                objectFiled = getClassInstance(writeMethod, false);
                convertToBean(objectFiled, jsonNode.toString());
                result = writeMethod.invoke(object, objectFiled);
                break;
            case ARRAY:
                objectFiled = getClassInstance(writeMethod, true);
                // 判断是否为数组
                Object array = convertToList(jsonNode.toString(), objectFiled.getClass());
                List<Object> list = List.of((Object[]) array);
                result = writeMethod.invoke(object, list);
                break;
            default:
                // debug用,不存在的类型需要添加
                System.out.println(jsonNode.toString());
                System.out.println(jsonNode.getNodeType());
                break;
        }
        return result;
    }

    /**
     * 类全限定名转类名
     *
     * @param clazz class
     * @return
     */
    public static String getTypeName(Class<?> clazz) {
        if (clazz == null) {
            return "";
        }
        String name = clazz.getName();
        return name.substring(name.lastIndexOf(".") + 1);
    }

    /**
     * 数组转集合
     *
     * @param arrayStr
     * @return
     */
    public static Object convertToList(String arrayStr, Class<?> clazz) {
        String substring = arrayStr.substring(1, arrayStr.length() - 1);
        String[] values = substring.split(",");
        Object o = Array.newInstance(clazz, values.length);
        for (int i = 0; i < values.length; i++) {
            String typeName = getTypeName(clazz);
            Object o1 = convertToTargetType(typeName, values[i].trim());
            Array.set(o, i, o1);
        }
        return o;
    }

    public static List convertToStrList(String arrayStr) {
        StringBuilder stringBuilder = new StringBuilder();
        char[] charArray = arrayStr.toCharArray();
        for (char c : charArray) {
            if ('[' == c || ']' == c) {
                stringBuilder.append("\"");
            } else if (',' == c) {
                stringBuilder.append("\",\"");
            } else if (' ' == c) {
                continue;
            }
        }
        return Arrays.asList(stringBuilder.toString());
    }

    /**
     * 类型转换
     *
     * @param targetName 目标名称
     * @param numStr     值
     * @return
     */
    public static Object convertToTargetType(String targetName, String numStr) {
        Object num = null;
        switch (targetName) {
            case "Byte":
                num = Byte.valueOf(numStr);
                break;
            case "Short":
                num = Short.valueOf(numStr);
                break;
            case "Integer":
                num = Integer.valueOf(numStr);
                break;
            case "Long":
                num = Long.valueOf(numStr);
                break;
            case "String":
                num = String.valueOf(numStr);
                break;
            case "byte[]":
                num = Byte.valueOf(numStr);
                break;
            case "short[]":
                num = Short.valueOf(numStr);
                break;
            case "int[]":
                num = Integer.valueOf(numStr);
                break;
            case "long[]":
                num = Long.valueOf(numStr);
                break;
            case "String[]":
                num = String.valueOf(numStr);
                break;
            default:
                System.out.println("未知类型:" + targetName);
                break;
        }
        return num;
    }

    /**
     * 获取className
     *
     * @param writeMethod set方法
     * @param isList      是否是集合
     * @return 对象
     * @throws Exception
     */
    public static Object getClassInstance(Method writeMethod, boolean isList) throws Exception {
        String typeName = writeMethod.getGenericParameterTypes()[0].getTypeName();
        String className = "";
        if (isList) {
            className = typeName.substring(typeName.lastIndexOf("<") + 1, typeName.length() - 1);
        } else {
            className = typeName;
        }
        return Class.forName(className).getDeclaredConstructor().newInstance();
    }

    /**
     * 下划线转驼峰
     *
     * @param name 值
     * @return
     */
    public static String underlineToUpperCase(String name) {
        char[] charArray = name.toCharArray();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < charArray.length; i++) {
            if ('_' == charArray[i]) {
                stringBuilder.append((charArray[++i] + "").toUpperCase());
            } else {
                stringBuilder.append(charArray[i]);
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 驼峰转下划线
     *
     * @param name
     * @return
     */
    public static String upperCaseToUnderline(String name) {
        char[] charArray = name.toCharArray();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < charArray.length; i++) {
            if (Character.isUpperCase(charArray[i])) {
                stringBuilder.append("_").append((charArray[i] + "").toLowerCase());
            } else {
                stringBuilder.append(charArray[i]);
            }
        }
        return stringBuilder.toString();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值