第6篇:`ObjectMapper`深度配置:全局行为定制
在前面的博文中,我们通过注解驱动(如
@JsonProperty
、@JsonFormat
)解决了JSON序列化/反序列化的局部需求——但当项目规模扩大(比如有上百个实体类),注解的局限性会逐渐凸显:
- 重复劳动:每个日期字段都要加
@JsonFormat
,每个驼峰字段都要加@JsonProperty
转下划线;- 规则混乱:不同开发者可能用不同注解(比如有的用
@JsonInclude
,有的手动过滤空值),导致JSON格式不统一;- 维护成本高:若需修改规则(比如日期格式从
yyyy-MM-dd
改为yyyy/MM/dd
),需逐个修改所有注解。而Jackson的核心类
ObjectMapper
,提供了全局配置能力——只需一次配置,就能统一项目所有JSON处理规则,彻底解决上述问题。本文将聚焦ObjectMapper
的四大核心全局配置,带你实现“一处配置,全域生效”。
一、前置知识:ObjectMapper
与配置的关系
ObjectMapper
是Jackson的“核心引擎”,负责JSON与Java对象的转换。它的配置体系主要分为两类:
- 特征配置:通过
SerializationFeature
(序列化特征)和DeserializationFeature
(反序列化特征)控制行为(如是否格式化、是否忽略未知字段); - 策略配置:通过
setPropertyNamingStrategy
(命名策略)、setDateFormat
(日期格式)等配置全局规则。
所有配置只需在ObjectMapper
实例化时设置一次,后续通过该实例进行的所有JSON操作都会遵循这些规则。在Spring项目中,可通过注入全局ObjectMapper
Bean,让所有@RestController
、RestTemplate
自动复用配置。
二、核心配置1:序列化全局规则(SerializationFeature
)
SerializationFeature
包含数十个序列化相关的开关,用于控制JSON输出的格式和内容。以下是项目中最常用的5个配置,覆盖90%的序列化场景。
1. 常用配置项解析
配置项 | 作用 | 默认值 | 适用场景 |
---|---|---|---|
INDENT_OUTPUT | 是否格式化输出JSON(换行、缩进) | false (紧凑格式) | 测试/开发环境便于调试;生产环境建议关闭(减少传输体积) |
WRITE_EMPTY_JSON_ARRAYS | 空集合(如new ArrayList<>() )是否序列化 | true (输出空数组[] ) | 生产环境建议关闭,避免返回"list":[] 这类冗余数据 |
WRITE_NULL_MAP_VALUES | Map中的null 值是否序列化 | true (输出"key":null ) | 全局过滤null值,替代@JsonInclude(Include.NON_NULL) |
WRITE_ENUMS_USING_TO_STRING | 枚举序列化时,使用toString() 结果还是枚举名 | false (用枚举名,如MALE ) | 若枚举重写了toString() (如返回中文“男”),需开启此配置 |
FAIL_ON_EMPTY_BEANS | 序列化空对象(无任何字段的类)是否报错 | true (报错) | 若项目中有空DTO(如标记类),需关闭避免报错 |
2. 代码示例:序列化全局配置
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;public class GlobalSerializeConfig {public static void main(String[] args) throws Exception {// 1. 实例化ObjectMapperObjectMapper objectMapper = new ObjectMapper();// 2. 配置序列化规则(全局生效)objectMapper// 开发环境开启格式化输出,生产环境注释此行.enable(SerializationFeature.INDENT_OUTPUT)// 关闭空集合序列化(避免返回"list":[]).disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)// 关闭null值序列化(避免返回"key":null).disable(SerializationFeature.WRITE_NULL_MAP_VALUES)// 枚举序列化用toString()结果(假设枚举重写了toString).enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)// 允许序列化空对象(无字段的类).disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);// 3. 测试:创建含空集合、null值、枚举的对象User user = new User();user.setUserName("张三");user.setAge(null); // null值,应被过滤user.setHobbies(new ArrayList<>()); // 空集合,应被过滤user.setGender(Gender.MALE); // 枚举,序列化用toString()(假设返回“男”)// 4. 序列化String json = objectMapper.writeValueAsString(user);System.out.println("全局配置后的序列化结果:");System.out.println(json);}// 测试实体类static class User {private String userName;private Integer age;private List<String> hobbies;private Gender gender;// getter/setter省略}// 枚举(重写toString()返回中文)enum Gender {MALE {@Overridepublic String toString() {return "男";}},FEMALE {@Overridepublic String