如何根据条件将同一JSON字段映射到不同数据类型的Java对象?
动态输出JSON字段类型的实现方案
你当前的POJO定义存在问题——两个字段使用相同的@JsonProperty会导致Jackson序列化/反序列化冲突,无法正常工作。要实现根据条件动态输出整数或小数类型的需求,可以通过以下几种方案解决:
方案一:自定义序列化器(推荐)
这种方式通过自定义Jackson序列化逻辑,根据条件动态决定输出的数值类型,结构更清晰。
1. 调整POJO结构
用单个Double类型字段存储数值(兼容整数和小数场景),同时添加条件标记:
public class Order { @JsonProperty("purchasedQty") @JsonSerialize(using = PurchasedQtySerializer.class) private Double purchasedQty; // 标记是否输出小数格式 private boolean outputDecimal; // 构造方法、getter/setter 省略 public boolean isOutputDecimal() { return outputDecimal; } public void setOutputDecimal(boolean outputDecimal) { this.outputDecimal = outputDecimal; } }
2. 实现自定义序列化器
创建序列化器,根据outputDecimal的值选择输出整数或小数:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class PurchasedQtySerializer extends JsonSerializer<Double> { @Override public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 获取当前序列化的Order对象 Order currentOrder = (Order) gen.getCurrentValue(); if (currentOrder.isOutputDecimal()) { // 输出小数格式 gen.writeNumber(value); } else { // 转换为整数后输出 gen.writeNumber(value.intValue()); } } }
3. 测试效果
import com.fasterxml.jackson.databind.ObjectMapper; public class SerializationTest { public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); // 条件为true,输出小数 Order decimalOrder = new Order(); decimalOrder.setPurchasedQty(1.0); decimalOrder.setOutputDecimal(true); System.out.println(mapper.writeValueAsString(decimalOrder)); // 输出: {"purchasedQty":1.0} // 条件为false,输出整数 Order integerOrder = new Order(); integerOrder.setPurchasedQty(1.0); integerOrder.setOutputDecimal(false); System.out.println(mapper.writeValueAsString(integerOrder)); // 输出: {"purchasedQty":1} } }
方案二:使用@JsonAnyGetter动态生成字段
如果不想修改原有字段结构,可以通过@JsonAnyGetter方法动态返回对应类型的数值:
import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; public class Order { private int purchasedQty; private double purchasedQtyDecimal; private boolean outputDecimal; @JsonAnyGetter public Map<String, Object> getDynamicPurchasedQty() { Map<String, Object> fieldMap = new HashMap<>(); if (outputDecimal) { fieldMap.put("purchasedQty", purchasedQtyDecimal); } else { fieldMap.put("purchasedQty", purchasedQty); } return fieldMap; } // getter/setter 省略 }
这种方式无需自定义序列化器,通过动态返回Map来控制输出的字段类型,适合需要保留原有两个字段的场景。
内容的提问来源于stack exchange,提问作者suku
相关产品推荐
相关产品推荐

