如何为含重复无序键的JSON编写Java反序列化POJO
针对该JSON结构的Java POJO编写方案
结构分析
目标JSON是一个数组,每个元素是仅含单个键的对象,键的类型包括oneImageBlock、fourImageBlock、oneTextBlock,同类型键可重复出现且顺序不固定,每个键对应一个元素列表(可能为空)。我们可以配合Jackson框架编写POJO实现反序列化。
1. 定义基础实体类
先提取JSON中复用的子结构,编写对应的POJO:
MobileImageOverride.java
public class MobileImageOverride { private String imagePath; // Getter & Setter public String getImagePath() { return imagePath; } public void setImagePath(String imagePath) { this.imagePath = imagePath; } }
CaptionTextReplacement.java
public class CaptionTextReplacement { private String type; // Getter & Setter public String getType() { return type; } public void setType(String type) { this.type = type; } }
ImageItem.java(图片块通用元素)
public class ImageItem { private String imagePath; private MobileImageOverride mobileImageOverride; private String imageAltText; private String imageCaptionText; private CaptionTextReplacement captionTextReplacement; private String urlPath; private Boolean displayURLInModal; // 所有字段的Getter & Setter public String getImagePath() { return imagePath; } public void setImagePath(String imagePath) { this.imagePath = imagePath; } public MobileImageOverride getMobileImageOverride() { return mobileImageOverride; } public void setMobileImageOverride(MobileImageOverride mobileImageOverride) { this.mobileImageOverride = mobileImageOverride; } public String getImageAltText() { return imageAltText; } public void setImageAltText(String imageAltText) { this.imageAltText = imageAltText; } public String getImageCaptionText() { return imageCaptionText; } public void setImageCaptionText(String imageCaptionText) { this.imageCaptionText = imageCaptionText; } public CaptionTextReplacement getCaptionTextReplacement() { return captionTextReplacement; } public void setCaptionTextReplacement(CaptionTextReplacement captionTextReplacement) { this.captionTextReplacement = captionTextReplacement; } public String getUrlPath() { return urlPath; } public void setUrlPath(String urlPath) { this.urlPath = urlPath; } public Boolean getDisplayURLInModal() { return displayURLInModal; } public void setDisplayURLInModal(Boolean displayURLInModal) { this.displayURLInModal = displayURLInModal; } }
MobileTextOverride.java
public class MobileTextOverride { private String text; // Getter & Setter public String getText() { return text; } public void setText(String text) { this.text = text; } }
TextItem.java(文本块元素)
public class TextItem { private String text; private String textAlignment; private MobileTextOverride mobileTextOverride; private String altText; private String urlPath; // 所有字段的Getter & Setter public String getText() { return text; } public void setText(String text) { this.text = text; } public String getTextAlignment() { return textAlignment; } public void setTextAlignment(String textAlignment) { this.textAlignment = textAlignment; } public MobileTextOverride getMobileTextOverride() { return mobileTextOverride; } public void setMobileTextOverride(MobileTextOverride mobileTextOverride) { this.mobileTextOverride = mobileTextOverride; } public String getAltText() { return altText; } public void setAltText(String altText) { this.altText = altText; } public String getUrlPath() { return urlPath; } public void setUrlPath(String urlPath) { this.urlPath = urlPath; } }
2. 定义块类型的多态POJO
利用Jackson的多态注解,统一处理不同类型的块:
Block.java(抽象父类)
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "blockType", visible = true ) @JsonSubTypes({ @JsonSubTypes.Type(value = OneImageBlock.class, name = "oneImageBlock"), @JsonSubTypes.Type(value = FourImageBlock.class, name = "fourImageBlock"), @JsonSubTypes.Type(value = OneTextBlock.class, name = "oneTextBlock") }) public abstract class Block { private String blockType; public String getBlockType() { return blockType; } public void setBlockType(String blockType) { this.blockType = blockType; } }
OneImageBlock.java(单图块)
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class OneImageBlock extends Block { @JsonProperty("oneImageBlock") private List<ImageItem> items; public List<ImageItem> getItems() { return items; } public void setItems(List<ImageItem> items) { this.items = items; } }
FourImageBlock.java(四图块)
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class FourImageBlock extends Block { @JsonProperty("fourImageBlock") private List<ImageItem> items; public List<ImageItem> getItems() { return items; } public void setItems(List<ImageItem> items) { this.items = items; } }
OneTextBlock.java(文本块)
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class OneTextBlock extends Block { @JsonProperty("oneTextBlock") private List<TextItem> items; public List<TextItem> getItems() { return items; } public void setItems(List<TextItem> items) { this.items = items; } }
3. 反序列化实现
使用Jackson的ObjectMapper将JSON字符串转换为List<Block>,再根据类型处理每个块:
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; public class BlockDeserializer { public static void main(String[] args) throws IOException { String jsonContent = "你的JSON字符串"; // 替换为实际JSON内容 ObjectMapper objectMapper = new ObjectMapper(); // 反序列化到块列表 List<Block> blocks = objectMapper.readValue( jsonContent, objectMapper.getTypeFactory().constructCollectionType(List.class, Block.class) ); // 遍历处理每个块 for (Block block : blocks) { if (block instanceof OneImageBlock) { OneImageBlock imgBlock = (OneImageBlock) block; // 处理单图块逻辑 } else if (block instanceof FourImageBlock) { FourImageBlock fourImgBlock = (FourImageBlock) block; // 处理四图块逻辑 } else if (block instanceof OneTextBlock) { OneTextBlock textBlock = (OneTextBlock) block; // 处理文本块逻辑 } } } }
注意事项
- 原JSON中
oneTextBlock的数组写法存在语法错误,正确格式应为[{"text": "test", ...}](数组包含对象)而非["text": "test", ...],需确保实际JSON符合规范。 - 需引入Jackson依赖(如
com.fasterxml.jackson.core:jackson-databind)到项目中。
内容的提问来源于stack exchange,提问作者ASHOK KUMAR
相关产品推荐
相关产品推荐

