Json字符串与Java对象互转工具类

常用的 JSON 处理库:

Jackson:这是最常用的库,它提供了各种特性,如生成/解析 JSON 的速度快,内存占用小,可扩展性强等。Jackson 支持类型安全,还具有复杂数据绑定的能力。
Gson:由 Google 开发,也是一个相当流行的库,使用起来非常简单。Gson 可以工作在任何 JDK 版本上,没有任何额外的依赖项。
Fastjson:这是 Alibaba 开发的 JSON库,性能好,使用起来简单。

在JavaWeb开发中,通常会使用Jackson库,因为SpringBoot已经内置了该库,不必在pom.xml中额外引入依赖。 以下代码为笔者写的Json转换工具类,使用起来比较简单方便

public class JsonUtils {

    /**
     * 静态成员会在类加载时初始化,并且在 JVM 的生命周期内通常不会被垃圾回收,除非类加载器被卸载
     */
    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
    
    /**
     * JSON字符串转指定类对象
     */
    public static <T> T toObject(String json, Class<T> clazz) throws IOException {
        return mapper.readValue(json, clazz);
    }


    /**
     * JSON字符串转泛型类对象
     */
    public static <T> T toObject(String json, TypeReference<T> type) throws IOException {
        return mapper.readValue(json, type);
    }

    /**
     * 对象转JSON字符串
     */
    public static String toJson(Object object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }

    /**
     * 数据库对象转VO对象
     *
     * @param source      数据库对象实例
     * @param targetClass VO类
     */
    public static <T, R> R convertToVo(T source, Class<R> targetClass) {
        return mapper.convertValue(source, targetClass);
    }

    /**
     * 数据库对象转VO对象,忽略指定属性
     *
     * @param source      数据库对象实例
     * @param targetClass VO类
     * @param properties  要忽略的属性
     */
    public static <T, R> R convertToVo(T source, Class<R> targetClass, String... properties) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
        ObjectNode objectNode = mapper.valueToTree(source);
        for (String property : properties) {
            objectNode.remove(property);
        }
        R targetObject = mapper.treeToValue(objectNode, targetClass);

        // 处理忽略的属性
        for (String property : properties) {
            Field field = targetClass.getDeclaredField(property);
            field.setAccessible(true);
            field.set(targetObject, getDefaultValue(field.getType()));
        }

        return targetObject;
    }

    private static Object getDefaultValue(Class<?> fieldType) {
        if (fieldType.isPrimitive()) {
            if (fieldType == boolean.class) return false;
            if (fieldType == char.class) return '\u0000';
            if (fieldType == byte.class || fieldType == short.class || fieldType == int.class || fieldType == long.class)
                return 0;
            if (fieldType == float.class) return 0f;
            if (fieldType == double.class) return 0d;
        }
        return null;
    }
}

 

在大部分场景下,该工具类已经可以满足字符串与对象之间的序列化和反序列化,可以不必额外引入FastJSON等依赖了。(基础场景、对象结构固定)

但是!如果你的反序列化的Object对象结构并非是固定不变的,那么还是强烈建议使用FastJSON等依赖!

posted @ 2023-07-12 11:33  Ashe|||^_^  阅读(321)  评论(0编辑  收藏  举报