
引言JSON序列化的重要性前后端数据交互的核心格式Spring Boot默认使用Jackson库的ObjectMapper为什么需要自定义JsonSerializer默认序列化无法满足特殊场景需求增强数据安全性、格式统一性、业务逻辑解耦本文目标深入解析JsonSerializer的五大实战应用场景提供可复用的代码示例一、JsonSerializer基础概念核心接口与类com.fasterxml.jackson.databind.JsonSerializerTSerializerProvider序列化上下文JsonGeneratorJSON生成器注册方式JsonSerialize注解指定字段全局注册SimpleModuleObjectMapperSlf4j Configuration public class JacksonConfig { Bean public Jackson2ObjectMapperBuilderCustomizer customizer() { return builder - { // 全局配置序列化返回 JSON 处理 JavaTimeModule javaTimeModule new JavaTimeModule(); javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); builder.modules(javaTimeModule); builder.timeZone(TimeZone.getDefault()); log.info(初始化 jackson 配置); }; } }二、核心应用方向与实战示例方向1敏感数据脱敏处理场景手机号、身份证号、邮箱等隐私数据部分隐藏实现public class PhoneSerializer extends JsonSerializerString { Override public void serialize(String value, JsonGenerator gen, SerializerProvider provider) { String masked value.replaceAll((\\d{3})\\d{4}(\\d{4}), $1****$2); gen.writeString(masked); } }使用JsonSerialize(using PhoneSerializer.class)方向2枚举类型语义化输出场景将Enum值转换为更友好的描述如ORDER_STATUS.PAID→ 已支付实现public class OrderStatusSerializer extends JsonSerializerOrderStatus { Override public void serialize(OrderStatus value, JsonGenerator gen, SerializerProvider provider) { gen.writeString(value.getDescription()); // 输出枚举的自定义描述字段 } }方向3日期时间格式化与时区处理场景统一全局日期格式如yyyy-MM-dd HH:mm:ss或动态时区转换实现public class LocalDateTimeSerializer extends JsonSerializerLocalDateTime { private static final DateTimeFormatter FORMATTER DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) { gen.writeString(value.format(FORMATTER)); } }方向4动态数据权限控制场景根据用户角色决定返回字段内容如管理员可见完整信息普通用户部分信息实现结合Spring Security获取当前用户角色动态构造JSON树JsonGenerator写入条件分支if (user.isAdmin()) { gen.writeStringField(salary, employee.getSalary()); } else { gen.writeStringField(salary, ****); }方向5自定义数据结构扁平化场景将嵌套对象转换为扁平键值对如{user: {name: Alice}}→{userName: Alice}实现public class UserFlattenSerializer extends JsonSerializerUser { Override public void serialize(User user, JsonGenerator gen, SerializerProvider provider) { gen.writeStartObject(); gen.writeStringField(userName, user.getName()); gen.writeStringField(deptName, user.getDept().getName()); gen.writeEndObject(); } }三、高级技巧与避坑指南处理空值重写isEmpty()方法控制空值序列化逻辑避免循环引用使用JsonIdentityInfo或手动控制序列化深度性能优化复用JsonSerializer实例线程安全设计避免在序列化中执行复杂计算或IO操作与反序列化配合配套实现JsonDeserializer保证数据双向转换一致性四、总结JsonSerializer的核心价值安全性敏感数据保护可读性数据结构友好化灵活性动态适配业务规则适用场景原则优先注解方案复杂逻辑再选全局注册避免过度自定义保持JSON结构可预测性