Jackson desearlization: two keys at the root. how do I deploy one and ignore the other?

using jackson 2.x

json's answer is as follows:

{
 "flag": true,
 "important": {
   "id": 123,
   "email": "foo@foo.com"
 }
}

The flag key does not provide any useful information. I would like to ignore the flag key and expand the “important” value in case of important.

public class Important {

    private Integer id;
    private String email;

    public Important(@JsonProperty("id") Integer id,
                     @JsonProperty("email") String email) {
        this.id = id;
        this.email = email;
    }

    public String getEmail() { this.email }

    public Integer getId() { this.id }
}

When I try to add @JsonRootName (“important”) to “Important” and configure ObjectMapper with DeserializationFeature.UNWRAP_ROOT_VALUE, I get a JsonMappingException:

The root name "flag" does not match the expected ("important") for type ...

When I remove the key / flag value from JSON, the data binding works just fine. I get the same result if I add @JsonIgnoreProperties ("flag") to the value of "Important".

UPDATES


updated class ... that will actually go through the compilation phase
@JsonRootName("important")
public static class Important {
    private Integer id;
    private String email;

    @JsonCreator
    public Important(@JsonProperty("id") Integer id,
                     @JsonProperty("email") String email) {
        this.id = id;
        this.email = email;
    }

    public String getEmail() { return this.email; }

    public Integer getId() { return this.id; }
}

actual test:

@Test
public void deserializeImportant() throws IOException {
    ObjectMapper om = new ObjectMapper();
    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    om.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
    Important important = om.readValue(getClass().getResourceAsStream("/important.json"), Important.class);

    assertEquals((Integer)123, important.getId());
    assertEquals("foo@foo.com", important.getEmail());
}

results:

com.fasterxml.jackson.databind.JsonMappingException: the root name "flag" does not match the expected ("important") type [simple type, class TestImportant $ Important]

+4
source share
1 answer

Just because of the streaming nature of JSON parsing in Jackson, I'm afraid there is no easy way to handle such cases.

From my point of view, this is easier to do with some kind of shell.

Consider this code:

public static class ImportantWrapper {
    @JsonProperty("important")
    private Important important;

    public Important getImportant() {
        return important;
    }
}

And the actual test:

@Test
public void deserializeImportant() throws IOException {
    ObjectMapper om = new ObjectMapper();
    //note: this has to be present
    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    Important important = om.readValue(getClass().getResourceAsStream("/important.json"), ImportantWrapper.class)
                                .getImportant();

    assertEquals((Integer)123, important.getId());
    assertEquals("foo@foo.com", important.getEmail());
}

Please note that it @JsonRootName("important")is redundant and can be removed in this case.

- , . "" , .

+1

All Articles