Force Jackson to ignore isEmpty without JsonIgnore
我在JAX-RS环境中使用Jackson和Jersey,并且引用了一个外部库,我只对其影响有限。 从这个外部库我使用一些dataholder / -model作为返回类型,它有一个与String.isEmpty()相当的isEmpty()方法
虽然序列化不是问题,但反序列化会导致以下异常,因为datamodel没有setEmpty()方法,而Jackson将isEmpty()方法解释为名为empty的字段。
1 2 | Unrecognized field"empty" (class de.unirostock.sems.cbarchive.meta.omex.VCard), not marked as ignorable (4 known properties:"givenName","organization","email","familyName"]) at [Source: org.glassfish.jersey.message.internal.EntityInputStream@36082d97; line: 1, column: 369] |
将@JsonIgnore添加到外部库不是一个选项,因为这会导致巨大的开销,我也不希望将数据持有者封装到另一个中,只是委托方法或在JavaScript中过滤字段。
还有其他可能迫使杰克逊忽视这个空洞的"场地"吗?
你可以使用Jackson的MixIn Annotations。
它允许您覆盖默认的Class配置。
通过这种方式,您可以使用
在你的例子中:
你有这个第三方类
声明一个MixIn类或接口:
1 2 3 4 | public interface VCardMixIn { @JsonIgnore boolean isEmpty(); } |
然后在杰克逊的
1 | objectMapper.getDeserializationConfig().addMixInAnnotations(VCard.class, VCardMixIn.class) |
假设您正在使用
1 2 | ObjectMapper om = new ObjectMapper(); om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
以下简单的测试说明了这一点(使用jackson-mapper-asl-1.9.10)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public static void main(String[] args) throws Exception { org.codehaus.jackson.map.ObjectMapper om = new org.codehaus.jackson.map.ObjectMapper(); om.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); String json ="{"one":"hola mundo!", "empty":"unknown", "someOtherUnknown":123}"; IgnoreUnknownTestDto dto = om.readValue(json, IgnoreUnknownTestDto.class); System.out.println(json+" DESERIALIZED AS"+dto); } public static class IgnoreUnknownTestDto { private String one; public String getOne() { return one; } public void setOne(String one) { this.one = one; } public boolean isEmpty() { return one == null || one.isEmpty(); } @Override public String toString() { return"one: '"+this.getOne()+"', empty: '"+this.isEmpty()+"'"; } } |
哪个输出:
1 | {"one":"hola mundo!","empty":"unknown","someOtherUnknown":123} DESERIALIZED AS one: 'hola mundo!', empty: 'false' |