Spring Boot中JsonSerializer的实战应用方向:提升API安全性、可读性与灵活性
引言
-
JSON序列化的重要性
-
前后端数据交互的核心格式
-
Spring Boot默认使用Jackson库的
ObjectMapper
-
-
为什么需要自定义JsonSerializer?
-
默认序列化无法满足特殊场景需求
-
增强数据安全性、格式统一性、业务逻辑解耦
-
-
本文目标
-
深入解析
JsonSerializer的五大实战应用场景 -
提供可复用的代码示例
-
一、JsonSerializer基础概念
-
核心接口与类
-
com.fasterxml.jackson.databind.JsonSerializer<T> -
SerializerProvider(序列化上下文) -
JsonGenerator(JSON生成器)
-
-
注册方式
-
@JsonSerialize注解指定字段 -
全局注册:
SimpleModule+ObjectMapper
-
@Slf4j
@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 JsonSerializer<String> { @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 JsonSerializer<OrderStatus> { @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 JsonSerializer<LocalDateTime> { 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 JsonSerializer<User> { @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结构可预测性
-
更多推荐



所有评论(0)