How to write the equivalent POJO for below type JSON :
[
{
"oneImageBlock": [{
"imagePath": "/abc",
"mobileImageOverride": {
"imagePath": "/abc"
},
"imageAltText": "image",
"imageCaptionText": "caption",
"captionTextReplacement": {
"type": "overlay"
},
"urlPath": "/url",
"displayURLInModal": true
}]
},
{
"fourImageBlock": [{
"imagePath": "/abc",
"mobileImageOverride": {
"imagePath": "/abc"
},
"imageAltText": "image",
"imageCaptionText": "caption",
"captionTextReplacement": {
"type": "overlay/Below Image"
},
"urlPath": "/l/123",
"displayURLInModal": true
},
{
"imagePath": "/abc",
"mobileImageOverride": {
"imagePath": "/abc"
},
"imageAltText": "image",
"imageCaptionText": "caption",
"captionTextReplacement": {
"type": "overlay/Below Image"
},
"urlPath": "/l/123",
"displayURLInModal": true
},
{
"imagePath": "/abc",
"mobileImageOverride": {
"imagePath": "/abc"
},
"imageAltText": "image",
"imageCaptionText": "caption",
"captionTextReplacement": {
"type": "overlay/Below Image"
},
"urlPath": "/l/123",
"displayURLInModal": true
},
{
"imagePath": "/abc",
"mobileImageOverride": {
"imagePath": "/abc"
},
"imageAltText": "image",
"imageCaptionText": "caption",
"captionTextReplacement": {
"type": "overlay/Below Image"
},
"urlPath": "/l/123",
"displayURLInModal": true
}
]
},
{
"fourImageBlock": [
]
},
{
"oneImageBlock": [
]
},
{
"oneTextBlock": [
"text": "test",
"textAlignment": "centre",
"mobileTextOverride": {
"text": "test"
},
"altText": "alt",
"urlPath": "/url"
]
},
{
"fourImageBlock": [
]
}
]
provided there can be multiple objects with the same key in the JSON like here in example it has 2 occurrence of oneImageBlock
& 3 occurrence of fourImageBlock
and also there is no fixed order as well i.e it's possible that in the JSON we have first 5 objects with fourImageBlock
followed by 2 objects with oneImageBlock
again followed by 2 objects with fourImageBlock
.
The easiest way to deserialize your data would be to set up some POJOs that conform to your JSON data:
Since your top-level objects can contain the keys: oneImageBlock
, fourImageBlock
, or oneTextBlock
, you need an object that defines all three of those as possibilities. They are defined in the Entry
class below.
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BlockDeserializer {
protected static ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) throws StreamReadException, DatabindException, IOException {
Entry[] entries = mapper.readValue(new File("src/main/resources/blocks.json"), Entry[].class);
System.out.println(entries);
}
private static class Entry {
public ImageBlock[] oneImageBlock;
public ImageBlock[] fourImageBlock;
public TextBlock[] oneTextBlock;
public TextBlock[] fourTextBlock;
}
private static class ImageBlock {
public String imagePath;
public MobileImageOverride mobileImageOverride;
public String imageAltText;
public String imageCaptionText;
public CaptionTextReplacement captionTextReplacement;
public String urlPath;
public boolean displayURLInModal;
}
private static class TextBlock {
public String text;
public String textAlignment;
public MobileTextOverride mobileTextOverride;
public String altText;
public String urlPath;
}
private static class CaptionTextReplacement {
public String type;
}
private static class MobileImageOverride {
public String imagePath;
}
private static class MobileTextOverride {
public String text;
}
}
Also, make sure your oneTextBlock
value is an array of objects. Looks like your JSON is invalid.
[
//...
{
"oneTextBlock": [
{
"text": "test",
"textAlignment": "centre",
"mobileTextOverride": {
"text": "test"
},
"altText": "alt",
"urlPath": "/url"
}
]
},
// ...
]
Alternatively, you can create your own deserializer so that you can correctly deserialize into the correct "block" type.
I removed the Entry
concept and added a Block
interface to all the sub-blocks.
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class BlockDeserializerDriver {
protected static ObjectMapper mapper;
protected static SimpleModule module;
static {
mapper = new ObjectMapper();
module = new SimpleModule();
module.addDeserializer(Block.class, new BlockDeserializer());
mapper.registerModule(module);
}
public static void main(String[] args) throws StreamReadException, DatabindException, IOException {
Block[] entries = loadBlocks("src/main/resources/blocks.json");
System.out.println(entries[0] instanceof OneImageBlock); // true
System.out.println(entries[1] instanceof FourImageBlock); // true
System.out.println(entries[2] instanceof FourImageBlock); // true
System.out.println(entries[3] instanceof OneImageBlock); // true
System.out.println(entries[4] instanceof OneTextBlock); // true
System.out.println(entries[5] instanceof FourImageBlock); // true
}
public static Block[] loadBlocks(String filePath) throws StreamReadException, DatabindException, IOException {
return mapper.readValue(new File(filePath), Block[].class);
}
private static interface Block {
}
private static class OneImageBlock implements Block {
public ImageBlock[] oneImageBlock;
}
private static class FourImageBlock implements Block {
public ImageBlock[] fourImageBlock;
}
private static class OneTextBlock implements Block {
public TextBlock[] oneTextBlock;
}
private static class FourTextBlock implements Block {
public TextBlock[] fourTextBlock;
}
private static class ImageBlock {
public String imagePath;
public MobileImageOverride mobileImageOverride;
public String imageAltText;
public String imageCaptionText;
public CaptionTextReplacement captionTextReplacement;
public String urlPath;
public boolean displayURLInModal;
}
private static class TextBlock {
public String text;
public String textAlignment;
public MobileTextOverride mobileTextOverride;
public String altText;
public String urlPath;
}
private static class CaptionTextReplacement {
public String type;
}
private static class MobileImageOverride {
public String imagePath;
}
private static class MobileTextOverride {
public String text;
}
// See: https://www.baeldung.com/jackson-deserialization
private static class BlockDeserializer extends StdDeserializer<Block> {
public BlockDeserializer() {
this(null);
}
public BlockDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Block deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode node = jp.getCodec().readTree(jp);
if (node.has("oneImageBlock")) {
return mapper.convertValue(node, OneImageBlock.class);
} else if (node.has("fourImageBlock")) {
return mapper.convertValue(node, FourImageBlock.class);
} else if (node.has("oneTextBlock")) {
return mapper.convertValue(node, OneTextBlock.class);
} else if (node.has("fourTextBlock")) {
return mapper.convertValue(node, FourTextBlock.class);
}
return null; // Could not parse Block
}
}
}