如何创建支持动态操作键JSON反序列化的Java POJO/DTO
动态操作键兼容的ListOfCondition DTO改造方案
问题场景
请求负载的list_of_conditions数组中,每个对象包含固定字段field_id、value,以及动态操作键(如show、modify,未来会新增更多类型)。现有ListOfCondition DTO仅支持show键,无法处理其他操作键的反序列化,需改造以实现通用兼容。
请求负载示例
"list_of_conditions": [ { "field_id": "QTrg9vq4S5uUs0yMnCpSVQ", "value": "monitor", "show": [ { "field_id": "7Q41FQvWSR2u4E5PiT39DQ", "required": true }, { "field_id": "FCqIf70iQJi48H-dC6xMEg" }, { "field_id": "vaTvFctJQgmhZq4F_liUBg" } ], "modify": [ { "field_id": "7Q41FQvWSR2u4E5PiT39DQ", "required": true, "newValue": "hello" } ] }, { "field_id": "QTrg9vq4S5uUs0yMnCpSVQ", "value": "monitor", "show": [ { "field_id": "7Q41FQvWSR2u4E5PiT39DQ", "required": true }, { "field_id": "FCqIf70iQJi48H-dC6xMEg" }, { "field_id": "vaTvFctJQgmhZq4F_liUBg" } ] } ]
现有DTO代码
@Data @Builder @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) @NoArgsConstructor @AllArgsConstructor public class ListOfCondition { @JsonProperty("id") private String id; @JsonProperty("field_id") private String fieldId; @JsonProperty("value") private String value; @JsonProperty("show") private List<ActionDTO> childFields; }
改造方案
利用Jackson的@JsonAnySetter和@JsonAnyGetter注解,结合Map存储动态操作键,实现对任意操作类型的兼容。
1. 改造ListOfCondition DTO
@Data @Builder @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) @NoArgsConstructor @AllArgsConstructor public class ListOfCondition { @JsonProperty("id") private String id; @JsonProperty("field_id") private String fieldId; @JsonProperty("value") private String value; // 存储所有动态操作:键为操作类型(如show/modify),值为对应ActionDTO列表 private Map<String, List<ActionDTO>> actions = new HashMap<>(); // 捕获所有未匹配到显式属性的JSON键值对,存入actions @JsonAnySetter public void setAction(String actionType, List<ActionDTO> actionData) { actions.put(actionType, actionData); } // 序列化时将actions中的键值对展开为JSON顶层属性(与请求格式一致) @JsonAnyGetter public Map<String, List<ActionDTO>> getActions() { return actions; } }
2. 兼容ActionDTO
由于不同操作类型的ActionDTO可能包含不同字段(如show的required、modify的newValue),需给ActionDTO添加@JsonIgnoreProperties(ignoreUnknown = true)以兼容未知字段:
@Data @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class ActionDTO { @JsonProperty("field_id") private String fieldId; private Boolean required; private String newValue; // 未来新增字段无需修改此类,@JsonIgnoreProperties会自动忽略未定义的字段 }
方案优势
- 扩展性强:无需修改DTO即可支持未来新增的操作类型(如
hide、disable等)。 - 完整兼容:完美反序列化所有动态操作键,保留操作类型与对应数据。
- 序列化一致:通过
@JsonAnyGetter保证序列化后的JSON格式与请求负载一致,便于数据持久化或回传。
内容的提问来源于stack exchange,提问作者Abhinaya Pandey
相关产品推荐
相关产品推荐

