使用Jackson将JSON映射为Java对象前如何对JSON字段进行自定义预处理
Jackson 字段映射自定义预处理实现方案
在Jackson将JSON结构映射为Java对象的过程中,完全可以满足字段赋值前插入自定义处理逻辑的需求,针对当前场景有3种可直接落地的实现方式,不需要引入额外依赖。
方案1:为目标类型绑定自定义反序列化器
该方式是最通用的实现路径,适合复用逻辑较多的场景:
- 新建继承
StdDeserializer<TotalNumber>的自定义反序列化类,在重写的deserialize方法中,先读取JSON字段的原始值(即示例中的整数数组[1,2,3,4]),执行需要的自定义处理(如数值过滤、聚合、格式转换等),最后构造符合要求的TotalNumber实例返回。 - 绑定反序列化器可选择两种粒度:
- 在
TotalNumber类定义上加@JsonDeserialize(using = 自定义反序列化器.class),项目内所有该类型的字段反序列化都会走这套逻辑 - 在
Numbers类的totalNumber成员变量上加同个注解,仅对当前类的该字段生效
- 在
核心反序列化器代码示例:
public class TotalNumberDeserializer extends StdDeserializer<TotalNumber> { @Override public TotalNumber deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 读取JSON原始数组值 Integer[] rawValues = p.readValueAs(Integer[].class); // 执行自定义预处理逻辑 int processedResult = Arrays.stream(rawValues).mapToInt(Integer::intValue).sum(); // 构造目标类型实例 TotalNumber target = new TotalNumber(); target.setInnerValue(processedResult); return target; } }
方案2:通过字段setter直接做预处理
如果预处理逻辑比较简单,不需要单独抽离独立类,可以直接在实体类的setter逻辑里嵌入自定义处理:
- 为
totalNumber字段自定义一个setter方法,用@JsonSetter("totalNumber")标注,让Jackson识别该方法作为字段的赋值入口 - 方法入参直接匹配JSON字段的原始结构(即接收
List<Integer>类型的数组值) - 在方法内部完成自定义处理后,再为
totalNumber成员赋值
代码示例:
public class Numbers { private TotalNumber totalNumber; @JsonSetter("totalNumber") public void assignTotalNumber(List<Integer> rawNumbers) { // 自定义预处理逻辑 TotalNumber processed = new TotalNumber(); processed.setInnerValue(rawNumbers.stream().mapToInt(Integer::intValue).max().orElse(0)); this.totalNumber = processed; } }
方案3:全局注册自定义处理逻辑
如果项目内多个类都存在同类型的字段预处理需求,不需要逐字段加注解,可以在初始化ObjectMapper时通过模块机制统一注册规则:
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); // 全局注册TotalNumber类型的自定义反序列化逻辑 customModule.addDeserializer(TotalNumber.class, new TotalNumberDeserializer()); objectMapper.registerModule(customModule);
注意:提供的示例JSON是顶层包裹数组的结构,即需要把整个JSON反序列化到
List<Numbers>类型时,上述所有方案的逻辑不受影响,不需要额外调整。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

