package com.iailab.framework.common.util.json; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; /** * JSON 工具类 * * @author iailab */ @Slf4j public class JsonUtils { private static ObjectMapper objectMapper = new ObjectMapper(); static { objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值 objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化 } /** * 初始化 objectMapper 属性 *

* 通过这样的方式,使用 Spring 创建的 ObjectMapper Bean * * @param objectMapper ObjectMapper 对象 */ public static void init(ObjectMapper objectMapper) { JsonUtils.objectMapper = objectMapper; } @SneakyThrows public static String toJsonString(Object object) { return objectMapper.writeValueAsString(object); } @SneakyThrows public static byte[] toJsonByte(Object object) { return objectMapper.writeValueAsBytes(object); } @SneakyThrows public static String toJsonPrettyString(Object object) { return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); } public static T parseObject(String text, Class clazz) { if (StrUtil.isEmpty(text)) { return null; } try { return objectMapper.readValue(text, clazz); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static T parseObject(String text, String path, Class clazz) { if (StrUtil.isEmpty(text)) { return null; } try { JsonNode treeNode = objectMapper.readTree(text); JsonNode pathNode = treeNode.path(path); return objectMapper.readValue(pathNode.toString(), clazz); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static T parseObject(String text, Type type) { if (StrUtil.isEmpty(text)) { return null; } try { return objectMapper.readValue(text, objectMapper.getTypeFactory().constructType(type)); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } /** * 将字符串解析成指定类型的对象 * 使用 {@link #parseObject(String, Class)} 时,在@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 的场景下, * 如果 text 没有 class 属性,则会报错。此时,使用这个方法,可以解决。 * * @param text 字符串 * @param clazz 类型 * @return 对象 */ public static T parseObject2(String text, Class clazz) { if (StrUtil.isEmpty(text)) { return null; } return JSONUtil.toBean(text, clazz); } public static T parseObject(byte[] bytes, Class clazz) { if (ArrayUtil.isEmpty(bytes)) { return null; } try { return objectMapper.readValue(bytes, clazz); } catch (IOException e) { log.error("json parse err,json:{}", bytes, e); throw new RuntimeException(e); } } public static T parseObject(String text, TypeReference typeReference) { try { return objectMapper.readValue(text, typeReference); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } /** * 解析 JSON 字符串成指定类型的对象,如果解析失败,则返回 null * * @param text 字符串 * @param typeReference 类型引用 * @return 指定类型的对象 */ public static T parseObjectQuietly(String text, TypeReference typeReference) { try { return objectMapper.readValue(text, typeReference); } catch (IOException e) { return null; } } public static List parseArray(String text, Class clazz) { if (StrUtil.isEmpty(text)) { return new ArrayList<>(); } try { return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static List parseArray(String text, String path, Class clazz) { if (StrUtil.isEmpty(text)) { return null; } try { JsonNode treeNode = objectMapper.readTree(text); JsonNode pathNode = treeNode.path(path); return objectMapper.readValue(pathNode.toString(), objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static JsonNode parseTree(String text) { try { return objectMapper.readTree(text); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static JsonNode parseTree(byte[] text) { try { return objectMapper.readTree(text); } catch (IOException e) { log.error("json parse err,json:{}", text, e); throw new RuntimeException(e); } } public static boolean isJson(String text) { return JSONUtil.isTypeJSON(text); } }