环境:Spring Boot3.2.5
1. 简介
Jackson ObjectMapper 是 Jackson 库的核心组件,在 Java 中广泛用于 JSON 序列化和反序列化。它提供了将 Java 对象转换为 JSON 格式(序列化)和反向转换(反序列化)的方法。ObjectMapper 可处理各种 JSON 数据格式和配置,使其成为在 Java 应用程序中处理 JSON 数据的通用工具。
以下是 Spring Boot 如何使用 Jackson ObjectMapper 处理 JSON 数据的概述:
序列化
从 Spring MVC 控制器返回 Java 对象时,Spring Boot 会使用 Jackson ObjectMapper 自动将这些对象序列化为 JSON 格式。
Jackson ObjectMapper 可根据 Java 对象的字段和属性将其转换为 JSON 表示形式。
反序列化
当接收到请求体(如 POST 或 PUT 请求)中的 JSON 数据时,Spring Boot 会使用 Jackson ObjectMapper 自动将 JSON 数据反序列化为相应的 Java 对象。
在反序列化过程中,Jackson ObjectMapper 会将 JSON 属性映射到 Java 对象的字段或属性。
定制化
Spring Boot 允许通过属性或 Bean 对 Jackson ObjectMapper 配置进行自定义。这包括配置日期格式化、空值处理和序列化/反序列化行为定制等功能。
下面是一个简单实用ObjectMapper的例子:
public class TestController {public MyObject getData() {MyObject data = new MyObject("Hello") ;return data ;}}
你访问该接口后会看到如下结果:
{"msg": "Hello"}
在上面的示例中,我们并没有显示的使用ObjectMapper对象将MyObject对象进行序列化为JSON格式。这都是因为Spring Boot在处理Controller返回值自动根据配置的默认ObjectMapper进行处理了。
2. 配置ObjectMapper
在 Spring Boot中,你可以通过@Bean 注解方式自定义 ObjectMapper Bean 来配置 Jackson ObjectMapper。这样,你就可以自定义 ObjectMapper 设置,如日期格式化、属性命名策略和序列化/反序列化功能,如下示例:
public ObjectMapper objectMapper() {ObjectMapper objectMapper = new ObjectMapper();// Customize ObjectMapper settings herereturn objectMapper ;}
注:Spring Boot底层自动配置不是直接创建ObjectMapper,它内部是还有其它很多自定义的配置。
自定义配置
public ObjectMapper objectMapper() {ObjectMapper objectMapper = new ObjectMapper() ;// 配置日期格式化objectMapper.setDateFormat(new StdDateFormat()) ;// 配置序列化objectMapper.enable(SerializationFeature.INDENT_OUTPUT);// 其它自定义配置return objectMapper ;}
如上自定义的配置,输出的数据如下:

当我们加入如下配置项后,对于null的字段不会输出
objectMapper.setSerializationInclusion(Include.NON_NULL) ;
上面的日期是标准日期格式,通过下面的设置可以修改自定义的格式
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) ;
Jackson还有其它很多的配置,你可以查看具体的API。
3. 序列化
在 Spring Boot 应用程序中,你可以通过配置 ObjectMapper 来自定义 JSON 序列化。这样就可以更改属性命名策略、在序列化过程中忽略属性以及添加自定义序列化器。以下是实现这些自定义的方法:
更改属性命名策略:你可以更改属性命名策略,将 Java 属性名转换为不同格式,如 snake_case、kebab-case 或 lowerCamelCase,如下示例:
@Beanpublic ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {return builder.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE).build() ;}
注:这里的Jackson2ObjectMapperBuilder 对象是Spring Boot自动配置的。
使用 PropertyNamingStrategy.SNAKE_CASE 策略,该策略在序列化过程中将 Java 属性名转换为 snake_case 格式。
在序列化过程中忽略属性:你可以在序列化过程中忽略特定属性,方法是使用 @JsonIgnore 对其进行注解,或配置 ObjectMapper 全局忽略这些属性,如下示例:
@Beanpublic ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {return builder.mixIn(MyData.class, MyDataMixin.class).build();}public class MyData {private String message;@JsonIgnoreprivate String secret;}public abstract class MyDataMixin {@JsonIgnoreprivate String secret ;}
如上示例,MyData 类的 secret 属性在序列化过程中使用 @JsonIgnore 被忽略。或者,也可以使用 mixins 将 ObjectMapper 配置为全局忽略属性。
添加自定义序列化器:你可以添加自定义序列化器,以便在序列化过程中处理特定类型或格式。如下示例:
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {ObjectMapper objectMapper = builder.build() ;SimpleModule module = new SimpleModule() ;module.addSerializer(MyCustomType.class, new MyCustomTypeSerializer()) ;objectMapper.registerModule(module) ;return objectMapper ;}public class MyCustomType {private String value ;}public class MyCustomTypeSerializer extends StdSerializer<MyCustomType> {public MyCustomTypeSerializer() {this(null) ;}public MyCustomTypeSerializer(Class<MyCustomType> t) {super(t) ;}public void serialize(MyCustomType value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeString(value.getValue().toUpperCase()) ;}}
如上示例中,我们为MyCustomType 类添加了一个自定义序列化器 MyCustomTypeSerializer,它在序列化过程中将值序列化为大写。
4. 反序列化
在 Spring Boot 应用程序中,你可以通过配置 ObjectMapper 来自定义 JSON 反序列化。这样,你就可以忽略未知属性、处理日期格式和时区并添加自定义反序列化器,如下示例:
忽略未知属性:你可以配置 ObjectMapper 在反序列化过程中忽略未知属性,这对于处理版本或不断演进的 API 非常有用。下面是一个示例:
@Beanpublic ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {return builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();}
在本示例中,我们配置 ObjectMapper 以禁用 FAIL_ON_UNKNOWN_PROPERTIES 功能,该功能会在反序列化过程中忽略未知属性。
处理日期格式和时区:你可以自定义 ObjectMapper 在反序列化过程中处理日期格式和时区的方式,如下示例:
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {ObjectMapper objectMapper = builder.build();// 配置日期格式及时区objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));objectMapper.setTimeZone(TimeZone.getTimeZone("UTC+8"));// 配置 Java 8 date/time 模块objectMapper.registerModule(new JavaTimeModule());objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);return objectMapper;}

