Spring Boot继承加载动态数据时JSON反序列化异常求助
问题背景
我尝试在Spring Boot中加载以下几种不同DataType的动态数据:
PLAIN_TEXT_INPUT("plain_text_input"), RADIO_BUTTONS("radio_buttons"), CHECKBOXES("checkboxes"), SELECT("select")
抛出的异常
not marked as ignorable (3 known properties: "actionId", "type", "text"])
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATIONdisabled); line: 12, column: 37] (through reference chain: configuration$Body["prefix"]->Prefix["aLevel"]->java.util.ArrayList[0]->xxx.$WidgetBase["placeholder"])
实体类代码
@Data public static class Prefix { @JsonProperty("aLevel") private List<WidgetBase> aLevel; } @Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = TextInput.class, name = "plain_text_input"), @JsonSubTypes.Type(value = RadioGroup.class, name = "radio_buttons"), @JsonSubTypes.Type(value = Select.class, name = "select"), @JsonSubTypes.Type(value = CheckBoxGroup.class, name = "checkboxes") }) public static class WidgetBase { @JsonProperty("actionId") private String actionId; @JsonProperty("type") private DataType type; @JsonProperty("text") private String text; } @Data public static class TextInput extends WidgetBase { @JsonProperty("placeholder") private String placeholder; @JsonProperty("description") private String description; } @Data public static class CheckBoxGroup extends WidgetBase { @JsonProperty("options") private List<CheckBoxOption> option_items; } @Data public static class Select extends WidgetBase { @JsonProperty("selected_item") private Option selected_item; @JsonProperty("select_items") private List<Option> select_items; } @Data public static class Option { @JsonProperty("text") private String text; @JsonProperty("value") private String value; }
请求Payload示例
"prefix":{ "aLevel":[{ "actionId":"plain_text_input_3", "type":"plain_text_input", "text":"Account ID", "placeholder":"Input your Account ID", "description":"Please enter the Account ID" },{ "actionId":"radio_group_action_3", "type":"radio_buttons", "text":"Radio Select", "initial_option":{"text":"Radio 1","value":"value1"}, "option_items":[{ "text":"Option 1","value":"value1" },{ "text":"Option 2","value":"value2" },{ "text":"Option 3","value":"value3" }] },{ "actionId":"checkbox_action_3", "text":"Checkbox Group", "type":"checkboxes", "options":[{ "text":"Option 1","value":"value1","initial_selected":true }] },{ "actionId":"select_action_3", "type":"select", "text":"This is static select label", "selected_item":{"text":"Option 1","value":"value1"}, "select_items":[{ "text":"Option 1","value":"value1" },{ "text":"Option 2","value":"value2" },{ "text":"Option 3","value":"value3" }] }] }
解决方案
问题根源
异常提示placeholder字段在WidgetBase中未被识别,说明Jackson没有正确根据type字段将JSON映射到对应的子类,而是用父类WidgetBase解析所有字段,导致子类独有的字段被判定为未知属性。
修复步骤
校验枚举与子类映射的一致性
确保DataType枚举的字符串值和@JsonSubTypes.Type中指定的name完全匹配,比如PLAIN_TEXT_INPUT的枚举值必须是"plain_text_input",否则Jackson无法匹配到对应子类。修正实体类的字段与Payload匹配问题
CheckBoxGroup类中,@JsonProperty("options")对应的字段名是option_items,但Payload中checkboxes类型的字段是"options",需修正字段名:@Data public static class CheckBoxGroup extends WidgetBase { @JsonProperty("options") private List<CheckBoxOption> options; // 从option_items改为options }- 补充缺失的
RadioGroup类:Payload中radio_buttons类型包含initial_option和option_items字段,实体类未定义该类,需添加:@Data public static class RadioGroup extends WidgetBase { @JsonProperty("initial_option") private Option initialOption; @JsonProperty("option_items") private List<Option> optionItems; } - 补充缺失的
CheckBoxOption类:Payload中checkboxes的options包含initial_selected字段,需定义该类:@Data public static class CheckBoxOption extends Option { @JsonProperty("initial_selected") private boolean initialSelected; }
添加未知字段忽略(可选)
如果Payload可能存在未定义的字段,可在WidgetBase上添加@JsonIgnoreProperties(ignoreUnknown = true),避免因额外字段抛出异常:@Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({...}) @JsonIgnoreProperties(ignoreUnknown = true) public static class WidgetBase { // 原有字段 }验证Jackson配置
确保Spring Boot默认的Jackson配置未被修改,默认配置支持多态类型解析,若有自定义配置需保证未禁用相关多态处理特性。
内容的提问来源于stack exchange,提问作者pintekus

