SpringBoot Rest API中RequestBody实体类接口类型字段如何用Jackson反序列化
实现方案
你可以直接使用Jackson原生提供的外部类型属性反序列化能力实现需求,无需编写自定义解析逻辑,步骤如下:
最优方案:使用Jackson内置类型映射注解
直接修改MoiChange类中的value字段,添加如下注解即可:
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; public class MoiChange { @JsonProperty("operation") private String operation = null; //operation值可为"Type1"或"Type2" // 新增以下3个注解实现类型自动映射 @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "operation" ) @JsonSubTypes({ @JsonSubTypes.Type(value = Type1MoiChangeValue.class, name = "Type1"), @JsonSubTypes.Type(value = Type2MoiChangeValue.class, name = "Type2") }) @JsonProperty("value") private OneOfMoiChangeValue value = null; // 原有getter、setter、其他属性保持不变 }
参数说明:
include = JsonTypeInfo.As.EXTERNAL_PROPERTY:指定类型标识字段是value字段的同级属性,而非value内部属性property = "operation":指定用来判断类型的字段名为operation@JsonSubTypes中的name要和operation的取值一一对应,关联到对应的实现类
配置完成后,Jackson会自动根据同级operation的取值,将value反序列化为对应的实现类实例。
备选方案:自定义反序列化器(仅适用于复杂类型判断场景)
如果你的业务有更复杂的类型判断逻辑,可以自定义反序列化器实现:
- 编写自定义反序列化类
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; public class MoiChangeDeserializer extends StdDeserializer<MoiChange> { public MoiChangeDeserializer() { super(MoiChange.class); } @Override public MoiChange deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode rootNode = p.getCodec().readTree(p); MoiChange moiChange = new MoiChange(); // 读取operation字段 String operation = rootNode.get("operation").asText(); moiChange.setOperation(operation); // 根据operation类型反序列化value JsonNode valueNode = rootNode.get("value"); OneOfMoiChangeValue value = switch (operation) { case "Type1" -> p.getCodec().treeToValue(valueNode, Type1MoiChangeValue.class); case "Type2" -> p.getCodec().treeToValue(valueNode, Type2MoiChangeValue.class); default -> throw new IllegalArgumentException("不支持的operation类型:" + operation); }; moiChange.setValue(value); // 其他字段可以在这里逐一读取赋值 return moiChange; } }
- 给
MoiChange类绑定反序列化器
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = MoiChangeDeserializer.class) public class MoiChange { // 原有属性、getter、setter保持不变 }
内容的提问来源于stack exchange,提问作者Surya
相关产品推荐
相关产品推荐

