diff --git a/snailmall-user-service/src/main/java/com/njupt/swg/common/utils/JsonUtil.java b/snailmall-user-service/src/main/java/com/njupt/swg/common/utils/JsonUtil.java index 12daca4..716f3b6 100644 --- a/snailmall-user-service/src/main/java/com/njupt/swg/common/utils/JsonUtil.java +++ b/snailmall-user-service/src/main/java/com/njupt/swg/common/utils/JsonUtil.java @@ -15,112 +15,134 @@ import java.text.SimpleDateFormat; /** * jackson的序列化和反序列化 */ +// 使用lombok的@Slf4j注解,用于自动生成日志相关的代码,方便在类中记录各种操作相关的日志信息,便于后续查看操作情况以及进行问题排查,例如在进行对象序列化、反序列化操作出现问题时,通过日志记录错误信息,有助于定位和解决问题。 @Slf4j public class JsonUtil { + // 创建一个ObjectMapper对象,ObjectMapper是Jackson库中用于处理JSON数据与Java对象之间相互转换的核心类,这里将其定义为静态成员变量,方便在整个类的各个静态方法中共享使用,避免重复创建对象,提高效率。 private static ObjectMapper objectMapper = new ObjectMapper(); + // 静态代码块,在类加载时执行,用于对ObjectMapper对象进行一系列的配置设置,以满足特定的JSON处理需求,确保在序列化和反序列化操作时按照期望的方式进行。 static { + // 设置序列化时包含所有字段,即无论字段的值是否为null,都将其列入进行转换,默认情况下有些配置可能会忽略null值字段,这里通过设置JsonSerialize.Inclusion.ALWAYS来确保所有字段都参与序列化,使得转换后的JSON数据能完整反映Java对象的结构。 //所有字段都列入进行转换 objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS); + // 取消默认将日期类型转换为时间戳形式的行为,改为按照指定的格式进行转换,这样在处理包含日期字段的Java对象转换为JSON时,日期会以更易读、符合业务需求的格式呈现,而不是以时间戳的形式出现,方便查看和使用。 //取消默认转换timestamp形式 - objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false); + objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); + // 配置忽略空bean(即没有属性值的Java对象)转JSON时的错误,避免在转换这样的对象时抛出异常,使得即使对象为空也能正常进行序列化操作,返回相应的JSON表示(可能为空对象的JSON形式)。 //忽略空bean转json的错误 - objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false); + objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false); + // 统一设置日期的格式,使用DateTimeUtil类中定义的标准格式("yyyy-MM-dd HH:mm:ss"),确保在整个应用中,涉及日期类型的序列化和反序列化操作都能按照这个统一的格式进行,保证日期数据的一致性和可读性。 //统一时间的格式 objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT)); + // 配置忽略JSON数据中存在属性,但对应的Java对象不存在该属性时的错误,这样在进行反序列化操作时,即使JSON数据包含一些Java对象中未定义的额外属性,也不会抛出异常,提高了对不同格式JSON数据的兼容性,方便处理一些可能存在扩展属性的情况。 //忽略json存在属性,但是java对象不存在属性的错误 - objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false); + objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); } /** - * 序列化方法,将对象转为字符串 - * @param obj - * @param - * @return + * 此静态方法是一个序列化方法,用于将给定的Java对象(obj)转换为JSON字符串表示形式,方便在网络传输、存储等场景中使用。 + * 如果传入的对象为null,则直接返回null,避免后续可能出现的空指针异常等问题。 + * 若对象不为null,则尝试进行转换,当对象本身就是字符串类型时,直接将其强制转换并返回(因为已经是期望的字符串形式了);否则,使用之前配置好的ObjectMapper对象的writeValueAsString方法将对象转换为JSON字符串,若在转换过程中出现IO异常(比如对象的结构不符合JSON序列化要求等原因导致),则会记录相应的警告日志(通过log.warn记录“parse object to string error”以及具体的异常信息),并返回null,表示转换失败,调用者可以根据返回值判断转换是否成功并进行相应的后续处理。 + * + * @param obj 要转换为JSON字符串的Java对象,可以是任意类型的对象,只要其结构符合JSON序列化的要求(根据ObjectMapper的配置以及JSON规范)。 + * @param 泛型标识,用于表示传入对象的类型可以是任意符合要求的类型,增加了方法的通用性,使其能处理不同类型的对象序列化需求。 + * @return 返回转换后的JSON字符串,如果传入对象为null或者转换过程出现异常则返回null,否则返回对应对象的JSON字符串表示形式。 */ - public static String obj2String(T obj){ - if(obj == null){ + public static String obj2String(T obj) { + if (obj == null) { return null; } try { - return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj); + return obj instanceof String? (String) obj : objectMapper.writeValueAsString(obj); } catch (IOException e) { - log.warn("parse object to string error",e); + log.warn("parse object to string error", e); return null; } } /** - * 序列化方法,同上,只是输出的格式是美化的,便于测试 - * @param obj - * @param - * @return + * 这个静态方法同样是序列化方法,功能与obj2String方法类似,也是将Java对象转换为JSON字符串,但它会输出美化后的格式,这种格式更便于在测试过程中查看和验证JSON数据的结构以及内容是否正确,使得JSON字符串的可读性更强,方便调试和检查。 + * 如果传入的对象为null,则直接返回null,避免后续出现问题。对于不为null的对象,在转换时,若对象本身是字符串类型则直接返回;否则,使用ObjectMapper对象的writerWithDefaultPrettyPrinter方法先获取一个能生成美化格式JSON字符串的写入器,再通过其writeValueAsString方法将对象转换为美化后的JSON字符串,若转换过程中出现IO异常,同样会记录警告日志并返回null,以便调用者知晓转换失败情况。 + * + * @param obj 要转换为美化格式JSON字符串的Java对象,类型可以是任意符合JSON序列化要求的对象。 + * @param 泛型标识,用于表示传入对象的类型具有通用性,能处理各种类型的对象进行美化格式的序列化操作。 + * @return 返回转换后的美化格式的JSON字符串,如果对象为null或者转换出现异常则返回null,否则返回对应对象的易读性更强的JSON字符串表示形式,方便测试查看。 */ - public static String obj2StringPretty(T obj){ - if(obj == null){ + public static String obj2StringPretty(T obj) { + if (obj == null) { return null; } try { - return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); + return obj instanceof String? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); } catch (IOException e) { - log.warn("parse object to string error",e); + log.warn("parse object to string error", e); return null; } } /** - * 比较简单的反序列化的方法,将字符串转为单个对象 - * @param str - * @param clazz - * @param - * @return + * 这是一个相对比较简单的反序列化方法,用于将给定的JSON字符串(str)转换为指定类型(clazz)的Java对象,方便从接收到的JSON数据中还原出对应的Java对象进行后续业务处理。 + * 如果传入的字符串为空(通过StringUtils.isEmpty方法判断)或者指定的目标类型(clazz)为null,则直接返回null,避免后续不必要的操作和可能出现的异常情况。 + * 若字符串和类型都有效,则先判断目标类型是否为String类型,如果是,则直接将传入的字符串强制转换并返回(因为本身就是期望的字符串类型了);否则,使用配置好的ObjectMapper对象的readValue方法,按照指定的类型(clazz)将JSON字符串解析为对应的Java对象,若在解析过程中出现IO异常(比如JSON字符串格式不符合目标对象结构要求等原因导致),则会记录警告日志并返回null,表示反序列化失败,调用者可以根据返回值判断是否成功还原出Java对象并进行后续业务逻辑处理。 + * + * @param str 要转换为Java对象的JSON字符串,其格式需要符合目标对象的结构要求(根据ObjectMapper的配置以及目标类型的定义)。 + * @param clazz 用于指定要转换生成的Java对象的类型,通过传入具体的Class对象来明确反序列化后的对象类型,例如传入User.class则表示要将JSON字符串转换为User类型的对象。 + * @param 泛型标识,用于表示返回的Java对象类型与传入的clazz参数指定的类型一致,增加了方法的通用性,能处理不同类型对象的反序列化需求。 + * @return 返回反序列化后的Java对象,如果传入的字符串为空或者目标类型为null或者解析过程出现异常则返回null,否则返回对应类型的Java对象,以便在业务中使用。 */ - public static T String2Obj(String str,Class clazz){ - if(StringUtils.isEmpty(str) || clazz == null){ + public static T String2Obj(String str, Class clazz) { + if (StringUtils.isEmpty(str) || clazz == null) { return null; } try { - return clazz.equals(String.class)?(T)str:objectMapper.readValue(str,clazz); + return clazz.equals(String.class)? (T) str : objectMapper.readValue(str, clazz); } catch (IOException e) { - log.warn("parse string to obj error",e); + log.warn("parse string to obj error", e); return null; } } /** - * 复杂对象的反序列化(通用) - * @param str - * @param typeReference - * @param - * @return + * 这是一个用于复杂对象反序列化的通用方法,适用于处理一些不能简单通过指定具体Class类型来反序列化的情况,例如处理包含泛型类型、嵌套复杂结构等的对象,通过传入TypeReference类型的参数来更精确地指定要反序列化的对象结构类型。 + * 如果传入的JSON字符串为空(通过StringUtils.isEmpty方法判断)或者传入的TypeReference对象为null,则直接返回null,避免后续无效操作和可能出现的异常。 + * 若字符串和TypeReference都有效,则先判断TypeReference所表示的类型是否为String类型,如果是,则直接返回传入的字符串(因为本身就是期望的字符串类型了);否则,使用配置好的ObjectMapper对象的readValue方法,按照TypeReference指定的复杂类型结构将JSON字符串解析为对应的Java对象,若在解析过程中出现IO异常,则记录警告日志并返回null,表示反序列化失败,调用者可根据返回值判断是否成功还原对象并进行后续处理。 + * + * @param str 要转换为复杂Java对象的JSON字符串,其格式需要符合TypeReference所指定的复杂对象结构要求。 + * @param typeReference 用于精确指定要反序列化的复杂对象的类型结构,通过TypeReference可以描述包含泛型、嵌套等复杂情况的对象类型,方便准确地从JSON字符串还原出对应的复杂Java对象。 + * @param 泛型标识,用于表示返回的Java对象类型与TypeReference指定的复杂类型一致,使得方法能处理各种复杂类型对象的反序列化需求,通用性更强。 + * @return 返回反序列化后的复杂Java对象,如果传入的字符串为空或者typeReference为null或者解析过程出现异常则返回null,否则返回对应复杂类型的Java对象,供业务中使用。 */ - public static T Str2Obj(String str, TypeReference typeReference){ - if(StringUtils.isEmpty(str) || typeReference == null){ + public static T Str2Obj(String str, TypeReference typeReference) { + if (StringUtils.isEmpty(str) || typeReference == null) { return null; } try { - return (T) (typeReference.getType().equals(String.class)?str:objectMapper.readValue(str,typeReference)); + return (T) (typeReference.getType().equals(String.class)? str : objectMapper.readValue(str, typeReference)); } catch (IOException e) { - log.warn("parse string to obj error",e); + log.warn("parse string to obj error", e); return null; } } /** - * 第二种方式实现复杂对象的反序列化 - * @param str - * @param collectionClass - * @param elementClasses - * @param - * @return + * 这是第二种实现复杂对象反序列化的方法,通过传入集合类型(collectionClass)以及元素类型(elementClasses)来构建JavaType对象,进而指定要反序列化的复杂对象结构,适用于处理集合类型且集合中元素类型明确的复杂对象反序列化情况。 + * 首先,通过ObjectMapper对象的getTypeFactory方法获取类型工厂对象,再使用其constructParametricType方法,传入集合类型和元素类型参数构建出JavaType对象,这个JavaType对象描述了要反序列化的复杂对象(集合及其中元素的类型结构)。 + * 然后,使用配置好的ObjectMapper对象的readValue方法,按照构建好的JavaType对象所指定的类型结构将JSON字符串解析为对应的Java对象,若在解析过程中出现IO异常,则记录警告日志并返回null,表示反序列化失败,调用者可以根据返回值判断是否成功还原对象并进行后续业务逻辑处理。 + * + * @param str 要转换为复杂Java对象(集合类型及其包含的元素构成的复杂结构)的JSON字符串,其格式需要符合构建的JavaType对象所指定的复杂对象结构要求。 + * @param collectionClass 用于指定集合类型,例如List.class、Set.class等,表示要反序列化的对象是哪种集合类型的结构。 + * @param elementClasses 可变参数,用于指定集合中元素的类型,按照顺序依次表示集合中元素的类型,例如传入User.class、Address.class等,表示集合中元素分别是对应的类型,通过这些参数构建出具体的复杂对象结构类型。 + * @param 泛型标识,用于表示返回的Java对象类型与构建的JavaType对象指定的复杂类型一致,使其能处理这种基于集合及元素类型的复杂对象反序列化需求,通用性更强。 + * @return 返回反序列化后的复杂Java对象,如果解析过程出现异常则返回null,否则返回对应类型的复杂Java对象,方便在业务中进行后续操作,比如对集合中的元素进行遍历、处理等。 */ - public static T Str2Obj(String str,Class collectionClass,Class... elementClasses){ - JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses); + public static T Str2Obj(String str, Class collectionClass, Class... elementClasses) { + JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); try { - return objectMapper.readValue(str,javaType); + return objectMapper.readValue(str, javaType); } catch (IOException e) { - log.warn("parse string to obj error",e); + log.warn("parse string to obj error", e); return null; } } -} +} \ No newline at end of file