xiejun
2024-11-01 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/jackson/JsonUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,705 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package org.springblade.core.tool.jackson;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.fasterxml.jackson.databind.type.MapType;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.*;
import org.springframework.lang.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.*;
/**
 * Jackson工具类
 *
 * @author Chill
 */
@Slf4j
public class JsonUtil {
   /**
    * å°†å¯¹è±¡åºåˆ—化成json字符串
    *
    * @param value javaBean
    * @return jsonString json字符串
    */
   public static <T> String toJson(T value) {
      try {
         return getInstance().writeValueAsString(value);
      } catch (Exception e) {
         log.error(e.getMessage(), e);
      }
      return null;
   }
   /**
    * å°†å¯¹è±¡åºåˆ—化成 json byte æ•°ç»„
    *
    * @param object javaBean
    * @return jsonString json字符串
    */
   public static byte[] toJsonAsBytes(Object object) {
      try {
         return getInstance().writeValueAsBytes(object);
      } catch (JsonProcessingException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param content   content
    * @param valueType class
    * @param <T>       T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(String content, Class<T> valueType) {
      try {
         return getInstance().readValue(content, valueType);
      } catch (Exception e) {
         log.error(e.getMessage(), e);
      }
      return null;
   }
   /**
    * å°†json反序列化成对象
    *
    * @param content       content
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(String content, TypeReference<T> typeReference) {
      try {
         return getInstance().readValue(content, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json byte æ•°ç»„反序列化成对象
    *
    * @param bytes     json bytes
    * @param valueType class
    * @param <T>       T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(byte[] bytes, Class<T> valueType) {
      try {
         return getInstance().readValue(bytes, valueType);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param bytes         bytes
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
      try {
         return getInstance().readValue(bytes, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param in        InputStream
    * @param valueType class
    * @param <T>       T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(InputStream in, Class<T> valueType) {
      try {
         return getInstance().readValue(in, valueType);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param in            InputStream
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
      try {
         return getInstance().readValue(in, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成List对象
    *
    * @param content      content
    * @param valueTypeRef class
    * @param <T>          T æ³›åž‹æ ‡è®°
    * @return List<T>
    */
   public static <T> List<T> parseArray(String content, Class<T> valueTypeRef) {
      try {
         if (!StringUtil.startsWithIgnoreCase(content, StringPool.LEFT_SQ_BRACKET)) {
            content = StringPool.LEFT_SQ_BRACKET + content + StringPool.RIGHT_SQ_BRACKET;
         }
         List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
         });
         List<T> result = new ArrayList<>();
         for (Map<String, Object> map : list) {
            result.add(toPojo(map, valueTypeRef));
         }
         return result;
      } catch (IOException e) {
         log.error(e.getMessage(), e);
      }
      return null;
   }
   /**
    * å°†json字符串转成 JsonNode
    *
    * @param jsonString jsonString
    * @return jsonString json字符串
    */
   public static JsonNode readTree(String jsonString) {
      Objects.requireNonNull(jsonString, "jsonString is null");
      try {
         return getInstance().readTree(jsonString);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json字符串转成 JsonNode
    *
    * @param in InputStream
    * @return jsonString json字符串
    */
   public static JsonNode readTree(InputStream in) {
      Objects.requireNonNull(in, "InputStream in is null");
      try {
         return getInstance().readTree(in);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json字符串转成 JsonNode
    *
    * @param content content
    * @return jsonString json字符串
    */
   public static JsonNode readTree(byte[] content) {
      Objects.requireNonNull(content, "byte[] content is null");
      try {
         return getInstance().readTree(content);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json字符串转成 JsonNode
    *
    * @param jsonParser JsonParser
    * @return jsonString json字符串
    */
   public static JsonNode readTree(JsonParser jsonParser) {
      Objects.requireNonNull(jsonParser, "jsonParser is null");
      try {
         return getInstance().readTree(jsonParser);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json byte æ•°ç»„反序列化成对象
    *
    * @param content   json bytes
    * @param valueType class
    * @param <T>       T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable byte[] content, Class<T> valueType) {
      if (ObjectUtil.isEmpty(content)) {
         return null;
      }
      try {
         return getInstance().readValue(content, valueType);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param jsonString jsonString
    * @param valueType  class
    * @param <T>        T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable String jsonString, Class<T> valueType) {
      if (StringUtil.isBlank(jsonString)) {
         return null;
      }
      try {
         return getInstance().readValue(jsonString, valueType);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param in        InputStream
    * @param valueType class
    * @param <T>       T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable InputStream in, Class<T> valueType) {
      if (in == null) {
         return null;
      }
      try {
         return getInstance().readValue(in, valueType);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param content       bytes
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable byte[] content, TypeReference<T> typeReference) {
      if (ObjectUtil.isEmpty(content)) {
         return null;
      }
      try {
         return getInstance().readValue(content, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param jsonString    jsonString
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable String jsonString, TypeReference<T> typeReference) {
      if (StringUtil.isBlank(jsonString)) {
         return null;
      }
      try {
         return getInstance().readValue(jsonString, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†json反序列化成对象
    *
    * @param in            InputStream
    * @param typeReference æ³›åž‹ç±»åž‹
    * @param <T>           T æ³›åž‹æ ‡è®°
    * @return Bean
    */
   @Nullable
   public static <T> T readValue(@Nullable InputStream in, TypeReference<T> typeReference) {
      if (in == null) {
         return null;
      }
      try {
         return getInstance().readValue(in, typeReference);
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°è£… map type
    *
    * @param keyClass   key ç±»åž‹
    * @param valueClass value ç±»åž‹
    * @return MapType
    */
   public static MapType getMapType(Class<?> keyClass, Class<?> valueClass) {
      return getInstance().getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
   }
   /**
    * å°è£… map type
    *
    * @param elementClass é›†åˆå€¼ç±»åž‹
    * @return CollectionLikeType
    */
   public static CollectionLikeType getListType(Class<?> elementClass) {
      return getInstance().getTypeFactory().constructCollectionLikeType(List.class, elementClass);
   }
   /**
    * è¯»å–集合
    *
    * @param content      bytes
    * @param elementClass elementClass
    * @param <T>          æ³›åž‹
    * @return é›†åˆ
    */
   public static <T> List<T> readList(@Nullable byte[] content, Class<T> elementClass) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyList();
      }
      try {
         return getInstance().readValue(content, getListType(elementClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content      InputStream
    * @param elementClass elementClass
    * @param <T>          æ³›åž‹
    * @return é›†åˆ
    */
   public static <T> List<T> readList(@Nullable InputStream content, Class<T> elementClass) {
      if (content == null) {
         return Collections.emptyList();
      }
      try {
         return getInstance().readValue(content, getListType(elementClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content      bytes
    * @param elementClass elementClass
    * @param <T>          æ³›åž‹
    * @return é›†åˆ
    */
   public static <T> List<T> readList(@Nullable String content, Class<T> elementClass) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyList();
      }
      try {
         return getInstance().readValue(content, getListType(elementClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content    bytes
    * @param keyClass   key类型
    * @param valueClass å€¼ç±»åž‹
    * @param <K>        æ³›åž‹
    * @param <V>        æ³›åž‹
    * @return é›†åˆ
    */
   public static <K, V> Map<K, V> readMap(@Nullable byte[] content, Class<?> keyClass, Class<?> valueClass) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyMap();
      }
      try {
         return getInstance().readValue(content, getMapType(keyClass, valueClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content    InputStream
    * @param keyClass   key类型
    * @param valueClass å€¼ç±»åž‹
    * @param <K>        æ³›åž‹
    * @param <V>        æ³›åž‹
    * @return é›†åˆ
    */
   public static <K, V> Map<K, V> readMap(@Nullable InputStream content, Class<?> keyClass, Class<?> valueClass) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyMap();
      }
      try {
         return getInstance().readValue(content, getMapType(keyClass, valueClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content    bytes
    * @param keyClass   key类型
    * @param valueClass å€¼ç±»åž‹
    * @param <K>        æ³›åž‹
    * @param <V>        æ³›åž‹
    * @return é›†åˆ
    */
   public static <K, V> Map<K, V> readMap(@Nullable String content, Class<?> keyClass, Class<?> valueClass) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyMap();
      }
      try {
         return getInstance().readValue(content, getMapType(keyClass, valueClass));
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * è¯»å–集合
    *
    * @param content bytes
    * @return é›†åˆ
    */
   public static Map<String, Object> readMap(@Nullable String content) {
      return readMap(content, String.class, Object.class);
   }
   /**
    * è¯»å–集合
    *
    * @param content bytes
    * @return é›†åˆ
    */
   public static List<Map<String, Object>> readListMap(@Nullable String content) {
      if (ObjectUtil.isEmpty(content)) {
         return Collections.emptyList();
      }
      try {
         return getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
         });
      } catch (IOException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * jackson çš„类型转换
    *
    * @param fromValue   æ¥æºå¯¹è±¡
    * @param toValueType è½¬æ¢çš„类型
    * @param <T>         æ³›åž‹æ ‡è®°
    * @return è½¬æ¢ç»“æžœ
    */
   public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
      return getInstance().convertValue(fromValue, toValueType);
   }
   /**
    * jackson çš„类型转换
    *
    * @param fromValue   æ¥æºå¯¹è±¡
    * @param toValueType è½¬æ¢çš„类型
    * @param <T>         æ³›åž‹æ ‡è®°
    * @return è½¬æ¢ç»“æžœ
    */
   public static <T> T convertValue(Object fromValue, JavaType toValueType) {
      return getInstance().convertValue(fromValue, toValueType);
   }
   /**
    * jackson çš„类型转换
    *
    * @param fromValue      æ¥æºå¯¹è±¡
    * @param toValueTypeRef æ³›åž‹ç±»åž‹
    * @param <T>            æ³›åž‹æ ‡è®°
    * @return è½¬æ¢ç»“æžœ
    */
   public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
      return getInstance().convertValue(fromValue, toValueTypeRef);
   }
   /**
    * tree è½¬å¯¹è±¡
    *
    * @param treeNode  TreeNode
    * @param valueType valueType
    * @param <T>       æ³›åž‹æ ‡è®°
    * @return è½¬æ¢ç»“æžœ
    */
   public static <T> T treeToValue(TreeNode treeNode, Class<T> valueType) {
      try {
         return getInstance().treeToValue(treeNode, valueType);
      } catch (JsonProcessingException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å¯¹è±¡è½¬ä¸º json node
    *
    * @param value å¯¹è±¡
    * @return JsonNode
    */
   public static JsonNode valueToTree(@Nullable Object value) {
      return getInstance().valueToTree(value);
   }
   /**
    * åˆ¤æ–­æ˜¯å¦å¯ä»¥åºåˆ—化
    *
    * @param value å¯¹è±¡
    * @return æ˜¯å¦å¯ä»¥åºåˆ—化
    */
   public static boolean canSerialize(@Nullable Object value) {
      if (value == null) {
         return true;
      }
      return getInstance().canSerialize(value.getClass());
   }
   public static Map<String, Object> toMap(String content) {
      try {
         return getInstance().readValue(content, Map.class);
      } catch (IOException e) {
         log.error(e.getMessage(), e);
      }
      return null;
   }
   public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
      try {
         Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
         });
         Map<String, T> result = new HashMap<>(16);
         for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), toPojo(entry.getValue(), valueTypeRef));
         }
         return result;
      } catch (IOException e) {
         log.error(e.getMessage(), e);
      }
      return null;
   }
   public static <T> T toPojo(Map fromValue, Class<T> toValueType) {
      return getInstance().convertValue(fromValue, toValueType);
   }
   public static ObjectMapper getInstance() {
      return JacksonHolder.INSTANCE;
   }
   private static class JacksonHolder {
      private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
   }
   private static class JacksonObjectMapper extends ObjectMapper {
      private static final long serialVersionUID = 4288193147502386170L;
      private static final Locale CHINA = Locale.CHINA;
      public JacksonObjectMapper(ObjectMapper src) {
         super(src);
      }
      public JacksonObjectMapper() {
         super();
         //设置地点为中国
         super.setLocale(CHINA);
         //去掉默认的时间戳格式
         super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
         //设置为中国上海时区
         super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
         //序列化时,日期的统一格式
         super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
         // å•引号
         super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
         // å…è®¸JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)
         super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
         super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
         super.findAndRegisterModules();
         //失败处理
         super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
         super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         //单引号处理
         super.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
         //反序列化时,属性不存在的兼容处理s
         super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
         //日期格式化
         super.registerModule(new BladeJavaTimeModule());
         super.findAndRegisterModules();
      }
      @Override
      public ObjectMapper copy() {
         return new JacksonObjectMapper(this);
      }
   }
}