Question

Given the following structure:

{"sheets" : [
    {"sheetName" : "Sheet 1", 
     "rows" : [{"0":"value1", "1":"value2"}, {...}]
    },
    {"sheetName" : "Sheet 2", 
     "rows" : [{"0":"value3", "1":"value4"}, {...}]
    },
    ...
 ]
}

How can I parse using jackson so that 'rows' mapping class is specified on runtime based on the attribute sheetName? e.g. 'Sheet 1' rows will map to class Sheet1[], 'Sheet 2' rows will map to class Sheet2[], and so on. JSON structure, specifically key names can't be changed so I can't just change each "row" key to correspond to a different sheet name.

Was it helpful?

Solution

I've solved this using the annotations @JsonTypeInfo and @JsonSubTypes on the generic class Sheet like the following:

public class Json {

public Sheet[] sheets = {};

@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="sheetName")
@JsonSubTypes({
    // list all sheet name : class mapping here
    @Type(name=MetadataSheet.sheetName, value=MetadataSheet.class)
})
static class Sheet {}

static class Sheet1 extends Sheet {
    public static final String sheetName = "Sheet 1";
    public Sheet1Rows[] rows; // subclasses a generic class Row
} 

}

This way, all sheets with a given sheet name will be mapped to a specific subclass of sheet and you can then just define the specific subclass of row you want inside the Sheet subclass i.e. Sheet1 can have Sheet1Rows[] field, etc.

I didn't find a way to just directly subclass the type of rows, because I think subclassing applies to the contained values, not the container but this gets the job done as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top