You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus Kafka Reactive反序列化子类PayloadModel时出现错误如何解决?

问题根因

  • 你的Kafka消息中payload、stepstatus字段是转义后的JSON字符串,而非原生嵌套JSON对象,Jackson默认不会自动将字符串值反序列化为Java对象,因此抛出找不到String入参构造器的错误
  • 字段名不匹配:消息中的currentstep、sagastatus等全小写字段,和模型类中的驼峰命名currentStep、sagaStatus不匹配;同时PayloadModel中定义的current字段,和消息payload中的balance字段名不一致
  • 当前的TransactionDeserializer继承了Quarkus自带的ObjectMapper反序列化器,默认仅处理原生JSON结构,不支持嵌套JSON字符串的自动解析

解决方案

方案1:调整消息发送逻辑(最优方案)

修改Kafka消息生产端的代码,不要将payload、stepstatus序列化为字符串,直接作为嵌套JSON对象发送,调整后的消息结构如下:

{"id":"73707ad2-0732-4592-b7e2-79b07c745e45","currentstep":"Debit-approval","payload": {"idCard": 2,"balance": 456,"pin":222},"sagastatus": "STARTED","stepstatus": {"credit-approval":"STARTED"},"type":"order-placement","version": 1}

同时调整模型类的字段映射:

  1. 给不匹配的字段添加@JsonProperty注解,或者调整字段名和消息完全一致
public class TransactionModel {
    public String id;
    @JsonProperty("currentstep")
    public String currentStep;
    public PayloadModel payload;
    @JsonProperty("sagastatus")
    public String sagaStatus;
    @JsonProperty("stepstatus")
    // 这里可以把stepStatus也改成对应的Map或者自定义对象,不用存字符串
    public Map<String, String> stepStatus;
    public String type;
    public String version;
    // 构造器省略
}
  1. 修正PayloadModel的字段定义:
public class PayloadModel {
    public Integer idCard;
    // 对应消息里的balance字段,或者直接把属性名改成balance
    @JsonProperty("balance")
    public Integer current;
    public Integer pin;
    // 构造器省略
}

方案2:发送端无法修改时,添加自定义反序列化逻辑

如果生产端消息结构不可变,给payload字段添加@JsonDeserialize注解,指定自定义的字符串转对象反序列化器:

  1. 先定义通用的JSON字符串反序列化器:
public class NestedJsonDeserializer<T> extends StdDeserializer<T> {
    private final Class<T> clazz;
    public NestedJsonDeserializer(Class<T> clazz) {
        super(clazz);
        this.clazz = clazz;
    }
    @Override
    public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String jsonStr = p.getValueAsString();
        return new ObjectMapper().readValue(jsonStr, clazz);
    }
}
  1. 在TransactionModel的payload字段上指定反序列化器:
public class TransactionModel {
    // 其他字段省略
    @JsonDeserialize(using = NestedJsonDeserializer.class)
    public PayloadModel payload;
    // stepstatus如果也要转对象同理加注解
}

再和方案1一样修正字段名映射即可解决问题。

不建议直接给PayloadModel加String入参的构造器手动解析,会增加冗余代码且不符合JSON序列化规范。

内容的提问来源于stack exchange,提问作者Edison Brito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:27:01