引言

  1. JSON序列化的重要性

    • 前后端数据交互的核心格式

    • Spring Boot默认使用Jackson库的ObjectMapper

  2. 为什么需要自定义JsonSerializer?

    • 默认序列化无法满足特殊场景需求

    • 增强数据安全性、格式统一性、业务逻辑解耦

  3. 本文目标

    • 深入解析JsonSerializer的五大实战应用场景

    • 提供可复用的代码示例


一、JsonSerializer基础概念

  1. 核心接口与类

    • com.fasterxml.jackson.databind.JsonSerializer<T>

    • SerializerProvider(序列化上下文)

    • JsonGenerator(JSON生成器)

  2. 注册方式

    • @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();
        }
    }

三、高级技巧与避坑指南

  1. 处理空值

    • 重写isEmpty()方法控制空值序列化逻辑

  2. 避免循环引用

    • 使用@JsonIdentityInfo或手动控制序列化深度

  3. 性能优化

    • 复用JsonSerializer实例(线程安全设计)

    • 避免在序列化中执行复杂计算或IO操作

  4. 与反序列化配合

    • 配套实现JsonDeserializer保证数据双向转换一致性


四、总结

  1. JsonSerializer的核心价值

    • 安全性:敏感数据保护

    • 可读性:数据结构友好化

    • 灵活性:动态适配业务规则

  2. 适用场景原则

    • 优先注解方案,复杂逻辑再选全局注册

    • 避免过度自定义,保持JSON结构可预测性

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐