jackson:如果一个财产丢失会发生什么?

如果我使用@JsonProperty注释构造函数参数,但Json没有指定该属性,会发生什么情况。 构造函数有什么价值?

如何区分具有空值的属性与JSON中不存在的属性?

总结程序员布鲁斯和斯塔克斯曼的优秀答案:

  1. 由构造函数引用的缺less属性被分配一个由Java定义的默认值。

  2. 您可以使用setter方法来区分隐式或显式设置的属性。 Setter方法只对具有显式值的属性调用。 Setter方法可以跟踪是否使用布尔标志(例如isValueSet )明确设置属性。

如果我使用@JsonProperty注释构造函数参数,但Json没有指定该属性,会发生什么情况。 构造函数有什么价值?

对于这样的问题,我喜欢写一个示例程序,看看会发生什么。

以下是这样一个示例程序。

 import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.map.ObjectMapper; public class JacksonFoo { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); // {"name":"Fred","id":42} String jsonInput1 = "{\"name\":\"Fred\",\"id\":42}"; Bar bar1 = mapper.readValue(jsonInput1, Bar.class); System.out.println(bar1); // output: // Bar: name=Fred, id=42 // {"name":"James"} String jsonInput2 = "{\"name\":\"James\"}"; Bar bar2 = mapper.readValue(jsonInput2, Bar.class); System.out.println(bar2); // output: // Bar: name=James, id=0 // {"id":7} String jsonInput3 = "{\"id\":7}"; Bar bar3 = mapper.readValue(jsonInput3, Bar.class); System.out.println(bar3); // output: // Bar: name=null, id=7 } } class Bar { private String name = "BLANK"; private int id = -1; Bar(@JsonProperty("name") String n, @JsonProperty("id") int i) { name = n; id = i; } @Override public String toString() { return String.format("Bar: name=%s, id=%d", name, id); } } 

结果是构造函数传递了数据types的默认值。

如何区分具有空值的属性与JSON中不存在的属性?

一种简单的方法是检查反序列化处理后的默认值,因为如果元素存在于JSON中但是具有空值,那么在给定相应的Java字段的情况下,将使用空值来replace任何默认值。 例如:

 import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; import org.codehaus.jackson.annotate.JsonMethod; import org.codehaus.jackson.map.ObjectMapper; public class JacksonFooToo { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY); // {"name":null,"id":99} String jsonInput1 = "{\"name\":null,\"id\":99}"; BarToo barToo1 = mapper.readValue(jsonInput1, BarToo.class); System.out.println(barToo1); // output: // BarToo: name=null, id=99 // {"id":99} String jsonInput2 = "{\"id\":99}"; BarToo barToo2 = mapper.readValue(jsonInput2, BarToo.class); System.out.println(barToo2); // output: // BarToo: name=BLANK, id=99 // Interrogate barToo1 and barToo2 for // the current value of the name field. // If it's null, then it was null in the JSON. // If it's BLANK, then it was missing in the JSON. } } class BarToo { String name = "BLANK"; int id = -1; @Override public String toString() { return String.format("BarToo: name=%s, id=%d", name, id); } } 

另一种方法是实现一个自定义的反序列化器来检查所需的JSON元素。 另一种方法是使用Jackson项目在http://jira.codehaus.org/browse/JACKSON上logging一个增强请求;

除了在@ Programmer_Bruce的答案中解释的构造函数行为之外,区分空值和缺失值的一种方法是定义一个setter:setter只是用显式的null值来调用。 自定义设置可以设置一个私有布尔标志(“isValueSet”或其他),如果你想跟踪设置值。

Setter优先于字段,如果field和setter都存在,那么你也可以用这种方式“覆盖”行为。

我正在考虑使用Option类的风格,其中一个Nothing对象会告诉我是否有这样的值。 有没有人和jackson(Java,而不是斯卡拉等)做过这样的事情?

(我的答案可能是有用的人通过谷歌find这个线程,即使它不回答OP问题)
如果你正在处理的是可以省略的原始types,并且你不想使用类似于其他答案中描述的setter(例如,如果你希望你的字段是最终的),你可以使用box对象:

 public class Foo { private final int number; public Foo(@JsonProperty Integer number) { if (number == null) { this.number = 42; // some default value } else { this.number = number; } } } 

如果JSON实际上包含null ,这不起作用,但如果知道它只包含原语或不存在就足够了