带有 Jackson 的 pojo 的嵌套映射

Nested map of a pojo with Jackson

我知道我可以使用 TypeReference 与 Jackson 创建指定对象的映射。例如,取 class ...

public class Error {    
    /** Error code */
    private final String errcode;
    /** Error message */
    private final String error; 
// Getter
}

...以及JSON

中的数据
{
   "firstError":{
      "errcode":"1234",
      "error":"The 1. message"
   },
   "secondError":{
      "errcode":"5678",
      "error":"The 2. message"
   }
}

...我可以用

反序列化
TypeReference<HashMap<String, Error>> typeRef  = new TypeReference<HashMap<String, Error>>() {};
Map<String, Error> map = new ObjectMapper().readValue(jsonInput, typeRef);

我现在的问题是:如果我的 JSON 看起来像这样,我该怎么办?

{
   "date":"2022-01-01",
   "server":"myfancyserver",
   "errors":{
      "firstError":{
         "errcode":"1234",
         "error":"The 1. message"
      },
      "secondError":{
         "errcode":"5678",
         "error":"The 2. message"
      }
   }
}

首先,为了反序列化包含final字段的嵌套Error对象,需要用@JCreator注解标记all-args构造函数,并使用@JsonProperty来正确设置值:

public class Error {
    private final String errcode;
    private final String error;

    @JsonCreator
    public Error(@JsonProperty("errcode") String errcode, @JsonProperty("error") String error) {
        this.errcode = errcode;
        this.error = error;
    }
    // ... getters/toString, etc.
}

那么应该使用ObjectMapper::convertValueJsonNode中读取map的内容:

String json = ...; // input JSON string

ObjectMapper om = new ObjectMapper();

JsonNode node = om.readTree(json); // throws JsonProcessingException 

Map<String, Error> errors = om.convertValue(
    node.get("errors"), new TypeReference<Map<String, Error>>(){}
);

errors.forEach((k, v) -> System.out.println(k + " = " + v));
// -> firstError = {errcode='1234', error='The 1. message'}
// -> secondError = {errcode='5678', error='The 2. message'}