Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a partial deserialization with Jackson

Tags:

java

jackson

In my REST microservice, I request an object from another service that returns me a huge nested JSON, for example:

{
  "address": "19th Street",
  "contact_info": {
     "phones": {
        "home": {
           "first": {
             "another_nested": 1234
           }
        }
     } 
  } 
}

What I need to fetch this data from another service, perform a change only in the first field, and then send it via HTTP. What I'm trying to avoid is to deserialize everything on my side and having to maintain the classes here. Is there a way to get the raw value of contact_info and just have the representation of address with Jackson? Something like this:

public class FullAddress {
  String address;
  RawValue contactInfo;
}
like image 281
bpereira Avatar asked Sep 25 '19 15:09

bpereira


People also ask

How does Jackson deserialization work?

Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter. Save this answer.

Which methods does Jackson rely upon to deserialize a JSON formatted string?

The @JsonSetter annotation tells Jackson to deserialize the JSON into Java object using the name given in the setter method. Use this annotation when your JSON property names are different to the fields of the Java object class, and you want to map them.


1 Answers

The simplest approach would be using JsonNode:

@Data
public class FullAddress {
    private String address;
    private JsonNode contactInfo;
}

Or either Map<String, Object>:

@Data
public class FullAddress {
    private String address;
    private Map<String, Object> contactInfo;
}

It works for both serialization and deserialization.


If you, however, wants to store the raw JSON, then you could define a custom deserializer:

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);
    }
}

And then use use it as follows:

@Data
public class FullAddress {

    private String address;

    @JsonDeserialize(using = RawJsonDeserializer.class)
    private String contactInfo;
}

For serializing back, however, you can annotate the contactInfo field with @JsonRawValue.

like image 74
cassiomolin Avatar answered Oct 24 '22 12:10

cassiomolin