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}
同时调整模型类的字段映射:
- 给不匹配的字段添加
@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; // 构造器省略 }
- 修正
PayloadModel的字段定义:
public class PayloadModel { public Integer idCard; // 对应消息里的balance字段,或者直接把属性名改成balance @JsonProperty("balance") public Integer current; public Integer pin; // 构造器省略 }
方案2:发送端无法修改时,添加自定义反序列化逻辑
如果生产端消息结构不可变,给payload字段添加@JsonDeserialize注解,指定自定义的字符串转对象反序列化器:
- 先定义通用的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); } }
- 在
TransactionModel的payload字段上指定反序列化器:
public class TransactionModel { // 其他字段省略 @JsonDeserialize(using = NestedJsonDeserializer.class) public PayloadModel payload; // stepstatus如果也要转对象同理加注解 }
再和方案1一样修正字段名映射即可解决问题。
不建议直接给PayloadModel加String入参的构造器手动解析,会增加冗余代码且不符合JSON序列化规范。
内容的提问来源于stack exchange,提问作者Edison Brito
相关产品推荐
相关产品推荐

