package com.emato.common.utils.oms; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.StringWriter; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.Locale; import java.util.Map; /** * JacksonUtils 工具类 * @author Scott Chen * @version 1.0 * 2017-09-18 18:42 */ public class JacksonUtils { private static final Logger logger = LoggerFactory.getLogger(JacksonUtils.class); private static ObjectMapper objectMapper; private static final ThreadLocal jacksonUtilThreadLocal = new ThreadLocal<>(); private static final ThreadLocal objectMapperThreadLocal = new ThreadLocal<>(); /** * 禁止调用无参构造 */ private JacksonUtils() {} /** * JacksonUtils 工具类实例 * @return */ public static JacksonUtils instance() { JacksonUtils instance = jacksonUtilThreadLocal.get(); if (instance == null) { instance = new JacksonUtils(); jacksonUtilThreadLocal.set(instance); } return instance; } /** * ObjectMapper实例 * @return */ public static ObjectMapper objectMapper() { objectMapper = objectMapperThreadLocal.get(); if (objectMapper== null){ objectMapper= new ObjectMapper(); // 格式化国家环境指定 objectMapper.setLocale(Locale.SIMPLIFIED_CHINESE); // 设置可见性 // PropertyAccessor: 属性访问器, IS_GETTER, getter-like methods that are named "isXxx" (instead of "getXxx" for getters) and return boolean value // Visibility: 可见性, PUBLIC_ONLY, 仅 public 修饰符 允许 objectMapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.PUBLIC_ONLY); // 序列化时, 当序列化数据中如果没有对应类型的数据时发生什么, 设置为true(默认),则会抛出异常,设置为false, 则会序列化为空对象 objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); // 反序列化时, 数据有值,但类型没有对应属性, 是否抛JsonMappingException异常, 默认为true, 抛出JsonMappingException objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 反序列化时, 允许空值("")是否转换为空对象`null` , 默认false, 不允许 objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); // 反序列化时, 多态的类型时会发生什么的, true(默认),抛出异常; 如果为false, 则使用null值 //objectMapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE); // 反序列化时, 确定遇到Object Id引用时会发生什么的, 默认true,抛出异常,false, 则不会进行进一步处理 //objectMapper.disable(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS); // 反序列化时, 属性注释不存在, 但关联的类型id可用的处理, 默认true, 抛出JsonMappingException objectMapper.disable(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY); // 序列化和反序列化时, 避免转义字符抛出异常情况 objectMapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS) ; // 序列化和反序列化时, 允许没有引号的字段名(非标准) objectMapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES); //设置null值不参与序列化(字段不被显示) objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // //注册序列化LocalDateTime模块 // objectMapper.registerModule(localDateTimeSerializer()); // //注册反序列化LocalDateTime模块 // objectMapper.registerModule(localDateTimeDeserializer()); // //注册序列化Date模块 // objectMapper.registerModule(dateTimeSerializer()); // //注册反序列化Date模块 // objectMapper.registerModule(dateTimeDeserializer()); //序列化Unicode编码非ASCII字符 //objectMapper.registerModule(unicodeSerModule()); objectMapperThreadLocal.set(objectMapper); } return objectMapper; } public ObjectMapper getObjectMapper() { return objectMapper(); } /** * 序列化Date * 自定义 * @return */ // private static SimpleModule dateTimeSerializer(){ // SimpleModule module = new SimpleModule(); // module.addSerializer(Date.class, new DateTimeSerializer()); // return module; // } /** * 反列化Date * 自定义 * @return */ // private static SimpleModule dateTimeDeserializer(){ // SimpleModule module = new SimpleModule(); // module.addDeserializer(Date.class, new DateTimeDeserializer()); // return module; // } /** * 序列化LocalDateTime时间 * 使用 jackson-datatype-jsr310 * @return */ // private static SimpleModule localDateTimeSerializer() { // SimpleModule module = new SimpleModule(); // module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE))); // module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE))); // module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE))); // return module; // } /** * 反序列化LocalDateTime时间 * 使用 jackson-datatype-jsr310 * @return */ // private static SimpleModule localDateTimeDeserializer() { // SimpleModule module = new SimpleModule(); // module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE))); // module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE))); // module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE))); // return module; // } /** * 序列化Unicode编码非ASCII字符 */ private static SimpleModule unicodeSerModule() { SimpleModule unicodeSerModule = new SimpleModule(); unicodeSerModule.addSerializer(String.class, new JacksonStringUnicodeSerializer()); return unicodeSerModule; } private static JsonFactory getJsonFactory() { return objectMapper().getFactory(); } // -------------------- to json -------------------- /** * bject对象序列化为Json字符串 * @param obj * @param * @return */ public static String toJsonStr(T obj) { return toJsonStr(obj, false); } /** * Object对象序列化为Json字符串 * * @param obj * @param isPretty 是否美化 * @param * @return */ public static String toJsonStr(T obj, boolean isPretty) { if (obj == null) { return null; } if (obj instanceof String) { return (String) obj; } StringWriter sw = new StringWriter(); JsonGenerator generator; try { generator = objectMapper().getFactory().createGenerator(sw); if (generator == null) { sw.close(); return null; } if (isPretty) { generator.useDefaultPrettyPrinter().writeObject(obj); } else { generator.writeObject(obj); } generator.close(); return sw.toString(); } catch (IOException ioe) { logger.error("toJSON序列化失败, 异常类型【IOException】, 错误原因:{}", ioe.getMessage()); ioe.printStackTrace(); return null; } } /** * Object对象序列化为Json字符串 * * @param obj * @param isPretty * @param * @return */ public static String toJsonStrWithObjectMapper(T obj, boolean isPretty) { if (obj == null){ return null; } if (obj instanceof String) { return (String) obj; } String result; try { if (isPretty) { result = objectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(obj); } else { result = objectMapper().writeValueAsString(obj); } return result; } catch (JsonProcessingException jpe) { logger.error("toJSON序列化失败, 异常类型【JsonProcessingException】, 错误原因:{}", jpe.getMessage()); jpe.printStackTrace(); return null; } } // -------------------- from json -------------------- /** * 将Json Byte反序列化成对象 * * @param data * @param clazz * @return */ public static T parseJson(byte[] data, Class clazz) { try { JsonParser parser = objectMapper().getFactory().createParser(data); return parser.readValueAs(clazz); } catch (IOException e){ logger.error(String.format("fromJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage())); } return null; } /** * 将Json String反序列化成对象 * * @param json * @param clazz * @return */ public static T parseJson(String json, Class clazz) { try { JsonParser parser = objectMapper().getFactory().createParser(json); return clazz.equals(String.class) ? (T) json : parser.readValueAs(clazz); } catch (IOException e) { logger.error(String.format("fromJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage())); logger.error("decode(String, Class)", e); } return null; } /** * 将Json Array或List反序列化为对象 * * @param json * @param typeReference 被转对象引用类型 * @param * @return */ public static T parseJson(String json, TypeReference typeReference) { try { JsonParser parser = objectMapper().getFactory().createParser(json); //写成List.class是不行的 return (T) (typeReference.getType().equals(String.class) ? json : parser.readValueAs(typeReference)); }catch (IOException e) { logger.error(String.format("fromJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage())); logger.error("decode(String, Class)", e); } return null; } /** * string转object 用于转为集合对象 * @param json json字符串 * @param collectionClass 被转集合class * @param elementClasses 被转集合中对象类型class * @param * @return */ public static T parseJson(String json, Class collectionClass, Class... elementClasses){ JavaType javaType = objectMapper() .getTypeFactory() .constructParametricType(collectionClass, elementClasses); try { return objectMapper().readValue(json, javaType); } catch (IOException e) { logger.error("Parse String to Object error."); e.printStackTrace(); return null; } } // -------------------- map to bean -------------------- /** * map 转 bean * @param map * @param clazz * @param * @return */ public static T mapToBean(Map map, Class clazz) { return objectMapper().convertValue(map, clazz); } }