【发布时间】:2018-03-06 20:55:34
【问题描述】:
我需要将 JsonArray 反序列化为布尔值。如果数组存在且不为空,则该值应设置为“true”。 问题是,我的自定义反序列化器虽然可以正常工作,但会破坏其余字段的反序列化 - 它们被设置为 null。
对象:
private static class TestObject {
private String name;
@JsonProperty("arr")
@JsonDeserialize(using = Deserializer.class)
private Boolean exists = null;
private Integer logins;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getExists() {
return exists;
}
public void setExists(boolean exists) {
this.exists = exists;
}
public Integer getLogins() {
return logins;
}
public void setLogins(Integer logins) {
this.logins = logins;
}
@Override
public String toString() {
return "TestObject{" +
"name='" + name + '\'' +
", exists=" + exists +
", logins=" + logins +
'}';
}
}
反序列化器:
public class Deserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
if (jp.getCurrentToken() == JsonToken.START_ARRAY) {
return true;
}
return false;
}
}
测试
@Test
public void test() throws JsonParseException, IOException {
Boolean result = deserialize();
}
private Boolean deserialize() throws IOException, JsonParseException,
JsonProcessingException {
TestObject testObject = mapper.readValue("{\n" +
" \"arr\": [\n" +
" {\"value\": \"New\"}\n" +
" ],\n" +
" \"name\": \"name\",\n" +
" \"logins\": 36" +
"}",
TestObject.class);
System.out.println(testObject.toString());
return testObject.getExists();
}
如果我删除“arr”数组或将其移动到 Json 的底部,一切都很好。如果我把它放在顶部 - TestObject{name='null', exists=true, logins=null}。
有一个类似的问题 (Jackson Custom Deserializer breaks default ones),但不幸的是它的答案为零。 由于当我重新排列 Json 时代码可以正常工作,所以看起来自定义反序列化器并非用于所有字段,而是 Jackson 在执行自定义反序列化器时停止反序列化。
【问题讨论】:
-
我的建议是不要将数组反序列化为布尔值。将数组反序列化为数组/列表/集并让
getExists返回arr != null或类似的。 -
@Paul 这确实有效,感谢您的想法,不知何故我没有想到这一点。问题是它看起来有点丑陋和晦涩,但如果没有其他方法我会这样做。
-
有时您必须在两个丑陋的解决方案中选择更漂亮的一个 :) 很高兴我能提供帮助...我会让我的评论成为答案。
标签: java json serialization jackson