Java Jackson反序列化包含/不带有自定义反序列化器的对象列表的对象吗?

时间:2018-08-20 12:27:23

标签: java json serialization jackson json-deserialization

我有这样的JSON输入

{
"slices": [{
        "slice": {
            "boundedBy": {
                "Envelope": {
                    "axisLabels": "Lat Long ansi",
                    "lowerCorner": "-44.975 111.975 \"2003-01-01T00:00:00+00:00\"",
                    "upperCorner": "-8.975 155.975 \"2003-01-01T00:00:00+00:00\"",
                    "srsDimension": 3
                }
            },
            "fileReferenceHistory": "/home/rasdaman/rasdaman_community/rasdaman/systemtest/testcases_services/test_all_wcst_import/testdata/wcs_local_metadata_tiff_no_specify_bands/GlobLAI-20030101-20030110-H01V06-1.0_MERIS-FR-LAI-HA.tiff",
            "local_metadata_key": "value_1"
        }
    },
    {
        "slice": {
            "boundedBy": {
                "Envelope": {
                    "axisLabels": "Lat Long ansi",
                    "lowerCorner": "-44.975 111.975 \"2003-10-01T00:00:00+00:00\"",
                    "upperCorner": "-8.975 155.975 \"2003-10-01T00:00:00+00:00\"",
                    "srsDimension": 3
                }
            },
            "fileReferenceHistory": "/home/rasdaman/rasdaman_community/rasdaman/systemtest/testcases_services/test_all_wcst_import/testdata/wcs_local_metadata_tiff_no_specify_bands/GlobLAI-20031001-20031010-H00V10-1.0_MERIS-FR-LAI-HA.tiff",
            "local_metadata_key": "value_2"
        }
    }
],
"Title": "Drought code", 
// other keys:values
}
带“ slices”的

是“ slice”对象的数组。在“切片”中没有任何“键”:“值”,但这不是问题。

然后,我有一个POJO类

public class CoverageMetadata {

       @JsonProperty(value = "slices")
       @JacksonXmlElementWrapper(useWrapping = false)
       private List<LocalMetadata> localMetadataList;

       private Map<String, String> globalMetadataAttributesMap;

       @JsonAnySetter
       public void addKeyValue(String key, String value) {
            this.globalMetadataAttributesMap.put(key, value);
       }

       @JsonAnyGetter
       public Map<String, String> getGlobalAttributesMap() {
            return globalMetadataAttributesMap;
       }

       // other gettters, setters without Jackson annotations

}

和列表中的一个类:

public class LocalMetadata {

    public static final String LOCAL_METADATA_TAG = "slice";

    private Map<String, String> localMetadataAttributesMap;

    private BoundedBy boundedBy;

    @JsonAnySetter
    // NOTE: To map an unknown list of properties, must use this annotation
    public void addKeyValue(String key, String value) {
        this.localMetadataAttributesMap.put(key, value);
    }


    public LocalMetadata() {
        this.localMetadataAttributesMap = new LinkedHashMap<>();
        this.boundedBy = new BoundedBy();
    }

    @JsonAnyGetter
    // NOTE: to unwrap the "map" from { "map": { "key": "value" } }, only keep { "key": "value" }
    public Map<String, String> getLocalMetadataAttributesMap() {
        return localMetadataAttributesMap;
    }

    public BoundedBy getBoundedBy() {
        return this.boundedBy;
    }

    public void setBoundedBy(BoundedBy boundedBy) {
        this.boundedBy = boundedBy;
    }

    public LocalMetadata(Map<String, String> localMetadataAttributesMap, BoundedBy boundedBy) {
        this.localMetadataAttributesMap = localMetadataAttributesMap;
        this.boundedBy = boundedBy;
    }
}

以及将JSON反序列化为对象的基本代码

ObjectMapper objectMapper = new ObjectMapper();
CoveageMetadata coverageMetadata = objectMapper.readValue(metadata, CoverageMetadata.class);

当我尝试反序列化CoverageMetadata对象的JSON输入时,出现错误

    Cannot deserialize coverage's metadata in XML/JSON by Jackson, error: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: {"slices":[{"slice":{"boundedBy":{"Envelope":{"axisLabels":"Lat Long ansi","srsDimension":3,"lowerCorner":"-44.975 111.975 \"2003-01-01T00:00:00+00:00\"","upperCorner":"-8.975 155.975 \"2003-01-01T00:00:00+00:00\""}},"local_metadata_key":"value_1","fileReferenceHistory":"/home/rasdaman/rasdaman_community/rasdaman/systemtest/testcases_services/test_all_wcst_import/testdata/wcs_local_metadata_tiff_no_specify_bands/GlobLAI-20030101-20030110-H01V06-1.0_MERIS-FR-LAI-HA.tiff"}}],"Title":"Drought code"}; line: 1, column: 21] (through reference chain: petascope.core.gml.metadata.model.CoverageMetadata["slices"]->java.util.ArrayList[0]->petascope.core.gml.metadata.model.LocalMetadata["slice"]).

如何将每个“切片”元素的JSON输入字符串反序列化为CoverageMetadataObject,将其映射到LocalMetadata对象?

1 个答案:

答案 0 :(得分:0)

简单的答案是,我创建另一个POJO类来保存“切片”列表,在CoverageMetadata类中,它将具有

public class CoverageMetadata {

     private Map<String, String> globalMetadataAttributesMap; 
     @JsonProperty(value = "slices")    
     private LocalMetadata localMetadata;

...
}

新的POJO类(之前的LocalMetadata类已重命名为LocalMetadataChild)

public class LocalMetadata {

    @JsonProperty(value = "slice")
    // This is the most important thing to avoid duplicate <slices><slices> when serializing in XML.
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<LocalMetadataChild> localMetadataList;

    public LocalMetadata(List<LocalMetadataChild> localMetadataList) {
        this.localMetadataList = localMetadataList;
    }

    public LocalMetadata() {
        this.localMetadataList = new ArrayList<>();
    }

    public List<LocalMetadataChild> getLocalMetadataList() {
        return localMetadataList;
    }

    public void setLocalMetadataList(List<LocalMetadataChild> localMetadataList) {
        this.localMetadataList = localMetadataList;
    }
}