无法修改依赖库时,如何自定义Jackson枚举反序列化?
解决Jackson枚举反序列化不匹配问题(无需修改DTO)
问题原因
依赖库的OrderStatus枚举用description字段存储API返回的字符串值(PartiallyFilledCanceled),但Jackson默认会用枚举的名称(比如PARTIALLY_FILLED_CANCELED)进行反序列化,导致字符串匹配失败抛出异常。
解决方案
通过自定义Jackson反序列化器,让Jackson根据枚举的description字段值匹配对应的枚举实例,全程无需修改依赖库的DTO或枚举类。
1. 编写自定义反序列化器
创建针对OrderStatus的反序列化器,遍历枚举实例匹配输入的字符串:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.api.client.domain.OrderStatus; import java.io.IOException; public class OrderStatusDeserializer extends StdDeserializer<OrderStatus> { protected OrderStatusDeserializer() { super(OrderStatus.class); } @Override public OrderStatus deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String inputValue = p.getText(); // 遍历所有枚举实例,匹配description字段 for (OrderStatus status : OrderStatus.values()) { if (status.getDescription().equals(inputValue)) { return status; } } // 未匹配到则抛出异常(也可根据需求返回null或默认值) throw new InvalidFormatException(p, "无法识别的订单状态", inputValue, OrderStatus.class); } }
2. 注册反序列化器到ObjectMapper
在你已有的ObjectMapper配置中,添加自定义反序列化器的注册:
// 保留原有配置 objectMapper.registerModule(new JavaTimeModule()); objectMapper.enable(JsonParser.Feature.IGNORE_UNDEFINED); objectMapper.coercionConfigFor(LogicalType.Enum).setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull); // 注册自定义枚举反序列化器 objectMapper.registerModule(new SimpleModule() .addDeserializer(OrderStatus.class, new OrderStatusDeserializer()));
原理说明
自定义反序列化器会覆盖Jackson对OrderStatus枚举的默认反序列化逻辑:当Jackson遇到需要反序列化为OrderStatus的字符串时,会调用我们的deserialize方法,通过枚举的description字段匹配对应的枚举实例,而非默认的枚举名称匹配。
内容的提问来源于stack exchange,提问作者Nicolazz92
相关产品推荐
相关产品推荐

