杰克逊desearlization:根源上的两个键。我怎么解开一个而忽略另一个?

时间:2014-09-15 21:14:37

标签: java json jackson

使用jackson 2.x

json响应如下所示:

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

"标志" key不提供任何有用的信息。我想忽略"标志"关键并打开"重要的"值为重要的实例。

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

当我尝试将@JsonRootName(" important")添加到Important并使用DeserializationFeature.UNWRAP_ROOT_VALUE配置ObjectMapper时,我收到一个JsonMappingException:

  

根名称'标记'类型...

与预期的(' important')不匹配

当我删除"标志"来自JSON的键/值数据绑定工作得很好。如果我将@JsonIgnoreProperties(" flag")添加到重要部分,我会得到相同的结果。

更新

<小时/> 更新的类......实际上将通过编译步骤

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

实际测试:

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

结果:

  
    

com.fasterxml.jackson.databind.JsonMappingException:根名称&#39;标记&#39;类型[简单类型,类TestImportant $重要]

与预期(&#39; important&#39;)不匹配   

1 个答案:

答案 0 :(得分:1)

仅仅因为杰克逊的JSON解析的流媒体特性,我担心没有简单的方法来处理这种情况。

从我的观点来看,使用某种包装器更容易。

考虑以下代码:

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

    public Important getImportant() {
        return important;
    }
}

实际测试:

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

请注意,@JsonRootName("important")是多余的,在这种情况下可以删除。

这看起来有些丑陋,但只需相对较小的努力即可完美运作。还有这样的&#34;包装&#34;可以是一般的,但这更像是建筑的东西。