如何使用 Jackson 进行部分反序列化

bpe*_*ira 4 java jackson

在我的 REST 微服务中,我从另一个服务请求一个对象,该对象返回一个巨大的嵌套 JSON,例如:

{
  "address": "19th Street",
  "contact_info": {
     "phones": {
        "home": {
           "first": {
             "another_nested": 1234
           }
        }
     } 
  } 
}
Run Code Online (Sandbox Code Playgroud)

我需要从另一个服务获取此数据,仅在第一个字段中执行更改,然后通过 HTTP 发送它。我试图避免的是反序列化我这边的所有内容,并且必须在这里维护类。有没有办法获得contact_info杰克逊的原始价值并只代表杰克逊的地址?像这样的东西:

public class FullAddress {
  String address;
  RawValue contactInfo;
}
Run Code Online (Sandbox Code Playgroud)

cas*_*lin 10

最简单的方法是使用JsonNode

@Data
public class FullAddress {
    private String address;
    private JsonNode contactInfo;
}
Run Code Online (Sandbox Code Playgroud)

或者Map<String, Object>

@Data
public class FullAddress {
    private String address;
    private Map<String, Object> contactInfo;
}
Run Code Online (Sandbox Code Playgroud)

它适用于序列化和反序列化。


但是,如果您想存储原始 JSON,那么您可以定义一个自定义反序列化器:

public class RawJsonDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt)
           throws IOException, JsonProcessingException {

        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        JsonNode node = mapper.readTree(jp);
        return mapper.writeValueAsString(node);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后按如下方式使用使用它:

@Data
public class FullAddress {

    private String address;

    @JsonDeserialize(using = RawJsonDeserializer.class)
    private String contactInfo;
}
Run Code Online (Sandbox Code Playgroud)

但是,对于序列化返回,您可以contactInfo使用@JsonRawValue.