在Spring Boot项目中,Jackson是处理JSON数据交换的核心组件。当业务模型里的字段类型不能被默认规则正确转换时,就需要我们主动介入序列化与反序列化流程。所谓序列化,是指把Java对象转为JSON字符串的过程;反序列化则是相反方向,将请求体中的JSON映射回Java对象。Spring Boot默认自动配置了一个ObjectMapper实例,所有通过RestController收发的JSON都经由它处理。如果我们不定制规则,像LocalDateTime、BigDecimal精度、枚举展示等问题就会直接暴露给前端或调用方。

使用注解定制字段级别的转换规则
最轻量的定制方式是在实体类的字段或方法上直接使用Jackson提供的注解。例如@JsonFormat可以指定日期时间的输出格式与时区,@JsonProperty能映射JSON属性名与Java字段名不一致的情况,@JsonIgnore则用于排除不需要参与序列化的字段。这些注解作用在具体的属性上,改动范围小,适合局部调整。当某个接口只需要微调个别字段时,注解方案直观且易于维护。
下面是一个使用注解控制日期与别名的示例。假设我们有一个用户实体,希望出生日期以yyyy-MM-dd格式输出,并且JSON中的字段名叫user_name而不是name:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
public class User {
private Long id;
@JsonProperty("user_name")
private String name;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date birthday;
// getter和setter省略
}
注解方式的短板在于侵入性强,配置分散在各个模型中。如果项目里有几十个类都需要相同的日期格式,挨个加@JsonFormat既繁琐又容易遗漏。此外,注解无法处理那些不属于你代码库的第三方类,例如引用的SDK里的数据类型。此时就需要更全局的手段。
编写自定义序列化器与反序列化器
当默认转换逻辑完全不符合需求时,可以继承StdSerializer和StdDeserializer编写自己的处理器。自定义序列化器接管某一种Java类型到JSON的写出逻辑,反序列化器则控制JSON到对象的读入逻辑。比如我们想让所有的Double类型在序列化时统一保留两位小数并以字符串形式返回,避免前端JavaScript因精度问题截断数字,就可以针对Double写一套规则。
下面代码展示了一个简单的自定义序列化器,把LocalDateTime转为yyyy-MM-dd HH:mm:ss字符串:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.serializer.StdSerializer;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CustomLocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public CustomLocalDateTimeSerializer() {
super(LocalDateTime.class);
}
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
if (value == null) {
gen.writeNull();
} else {
gen.writeString(value.format(FORMATTER));
}
}
}
写好序列化器后,还需要通过模块(Module)把它注册到ObjectMapper中才会生效。Spring Boot里可以通过Jackson2ObjectMapperBuilderCustomizer或者直接使用@Bean定义Module来装配。自定义序列化器灵活度最高,可以处理任意复杂结构的转换,但代价是代码量偏大,且每个特殊类型都要配对维护,适合确实有特殊协议要求的场景。
全局配置ObjectMapper与Spring Boot集成
如果希望整套规则对项目里所有接口统一生效,最佳实践是定制Spring Boot自动创建的ObjectMapper。我们可以通过application.properties关闭默认的一些特性,例如spring.jackson.date-format设置全局日期格式;也可以在配置类里声明Jackson2ObjectMapperBuilderCustomizer Bean,在回调中统一注册模块、设置时区、关闭WRITE_DATES_AS_TIMESTAMPS等。这种方式不修改业务模型,集中管理,便于团队统一规范。
下面示例演示如何注册前面写的LocalDateTime序列化器,并统一关闭把日期写成时间戳的行为:
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.SerializationFeature;
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(new CustomLocalDateTimeSerializer());
builder.modulesToInstall(module);
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.timeZone("GMT+8");
};
}
}
需要留意的是,Spring Boot 2.3之后对Java 8时间类型的支持已经内置了JavaTimeModule,若直接引入jackson-datatype-jsr310依赖,默认就会注册。但默认序列化仍是数组形式,所以像上例那样用自定义序列化器覆盖才是控制格式的关键。全局配置避免了注解的分散,也解决了第三方类无法加注解的难题。当规则变更时,只需改这一处配置,全项目立即同步,是大型应用推荐的做法。
对比三种方案:注解适合快速局部修复,自定义序列化器适合特殊类型协议,全局配置适合统一规范。实际项目中往往组合使用,例如全局定好日期格式基线,个别字段再用@JsonIgnore做排除。理解Jackson在Spring Boot里的自动装配链路,才能确保自己写的规则真正落在处理JSON的ObjectMapper上,而不是被另一条配置覆盖。
Spring_BootJacksonJSON序列化修改时间:2026-08-17 15:46:32