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

Spring Boot请求嵌套类反序列化问题及注解方案咨询

Spring Boot请求嵌套类反序列化问题

在Spring Boot中处理请求反序列化时,遇到第一层属性正常映射,但嵌套字段无法映射到对应子类的问题。

相关代码

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CustomForm extends GenericJson {

    private String formId;

    private CustomInfo info;

    private List<CustomItem> items = new ArrayList<>();
    
    private String linkedSheetId;
    
    private String responderUri;
    
    private String revisionId;
    
    private FormSettings settings;

    public CustomForm(Form form){
        BeanUtils.copyProperties(form, this);
        if(form.getInfo() != null){
            this.info = new CustomInfo(form.getInfo());
        }
        if(form.getItems() != null){
            for(Item item:form.getItems()){
                this.items.add(new CustomItem(item));
            }
        }
    }

    public Form getForm(){
        Form form = new Form();
        BeanUtils.copyProperties(this, form);
        List<Item> items = new ArrayList<>();
        for(CustomItem item:this.items){
            items.add(item.getItem());
        }
        form.setItems(items);
        if(!this.info.isEmpty()) {
            form.setInfo(this.info.getInfo());
        }
        return form;
    }
}

请求示例

{
    "formId": "1234",
    "info": {
        "documentTitle": "Untitled form",
        "title": "prova"
    },
    "items": [
        {
            "itemId": "123",
            "questionItem": {
                "question": {
                    "choiceQuestion": {
                        "options": [
                            {
                                "value": "Newsletter"
                            },
                            {
                                "value": "Magazine"
                            },
                            {
                                "value": "Social Network"
                            },
                            {
                                "value": "Siti"
                            },
                            {
                                "value": "Associazioni di categoria"
                            },
                            {
                                "value": "Aziende partner"
                            },
                            {
                                "value": "Comunicazione interna all'azienda"
                            }
                        ],
                        "type": "DROP_DOWN"
                    },
                    "questionId": "123"
                }
            },
            "title": "Come sei venuto a conoscenza di questo Corso?"
        },
        {
            "itemId": "123",
            "questionGroupItem": {
                "grid": {
                    "columns": {
                        "options": [
                            {
                                "value": "PESSIMO"
                            },
                            {
                                "value": "MEDIOCRE"
                            },
                            {
                                "value": "SUFFICIENTE"
                            },
                            {
                                "value": "BUONO"
                            },
                            {
                                "value": "OTTIMO"
                            }
                        ],
                        "type": "RADIO"
                    }
                },
                "questions": [
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Pulizia delle aule"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Materiale fornito"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Competenza docente"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Completezza contenuti"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Applicabilità delle nozioni"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Rispondenza ad aspettative"
                        }
                    },
                    {
                        "questionId": "123",
                        "rowQuestion": {
                            "title": "Gentilezza del personale"
                        }
                    }
                ]
            }
        }
    ],
    "responderUri": "https://example.om",
    "revisionId": "00000005"
}

提问:是否存在注解可将请求字段与对应嵌套类关联?


解决方案

可以通过Jackson的注解解决嵌套类的反序列化映射问题,以下是关键注解和注意事项:

1. 基础字段映射:@JsonProperty

如果请求字段名与嵌套类属性名存在差异(比如大小写、驼峰/下划线格式不同),直接在嵌套类的属性上添加@JsonProperty指定对应JSON字段名。示例:

@Getter
@Setter
@NoArgsConstructor
public class CustomInfo {
    @JsonProperty("documentTitle")
    private String documentTitle;
    @JsonProperty("title")
    private String title;
}

若字段名完全匹配,该注解可省略,但必须确保嵌套类有无参构造方法(Jackson反序列化的必要条件),且属性配有@Getter/@Setter或公有的getter/setter方法。

2. 多态嵌套类处理:@JsonTypeInfo + @JsonSubTypes

如果CustomItem是父类,请求中的questionItem、questionGroupItem对应不同子类,需要用这两个注解指定类型识别规则。示例:

@Getter
@Setter
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "itemType")
@JsonSubTypes({
    @JsonSubTypes.Type(value = QuestionItem.class, name = "questionItem"),
    @JsonSubTypes.Type(value = QuestionGroupItem.class, name = "questionGroupItem")
})
public class CustomItem {
    private String itemId;
    private String title;
    private String itemType; // 用于标识子类类型的字段
}

通过JSON中指定的字段区分要实例化的子类,确保不同类型的嵌套对象能正确反序列化。

3. 核心注意事项

  • 所有嵌套类(CustomInfo、CustomItem、FormSettings等)必须添加@NoArgsConstructor,Jackson依赖无参构造创建对象。
  • 嵌套类的所有属性必须配有getter/setter方法(可通过Lombok的@Getter/@Setter快速实现)。
  • 检查GenericJson类是否覆盖了Jackson的默认序列化逻辑,避免干扰嵌套类的映射处理。

内容的提问来源于stack exchange,提问作者Luca Pisoni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:14:55