我认为您不应该在这种情况下使用Optional。正如@dkatzel 在他的回答中提到的那样,它应该被用作 API 返回值而不是字段。
尽管有这种学术讨论,但您只需将 Data 类中的字段初始化为其默认值即可完成您想要的操作:
public class Data {
private String field = DEFAULT_VALUE;
}
然后让杰克逊做剩下的。
根据 OP 的评论进行编辑:
当您的 JSON 带有 field 的 null 值时,Jackson 会将其设置为 null,这就是将存储在数据库中的内容。
当您的 JSON 不包含该字段时,DEFAULT_VALUE 将自动加载到您的 Data 实例中。
当您的 JSON 确实包含 field 的值时,Jackson 将设置它,并且该值将到达数据库。
编辑 2,考虑到 OP 要求在解析 JSON 输入后找出 field 是否已填写、设置为 null 或在输入 JSON 中不存在:
如果,解析输入 JSON 后,您需要知道 field 是否被填写、设置为 null 或不存在,然后考虑这个例子,它显示了方法我会接受:
public class Data {
private String field1 = "hello";
private Integer field2 = 10;
private Double field3 = 3.75;
private static final Data DEFAULTS = new Data(); // defaults will be kept here
public String getField1() {
return this.field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Integer getField2() {
return this.field2;
}
public void setField2(Integer field2) {
this.field2 = field2;
}
public Double getField3() {
return this.field3;
}
public void setField3(Double field3) {
this.field3 = field3;
}
@Override
public String toString() {
return "Data [field1=" + this.field1 +
", field2=" + this.field2 +
", field3=" + this.field3 + "]";
}
public boolean isDefault(Function<Data, Object> getter) {
Object defaultProperty = getter.apply(DEFAULTS);
Object actualProperty = getter.apply(this);
return defaultProperty != null // needed to support fields with no default value
&& defaultProperty.equals(actualProperty);
}
public boolean isNull(Function<Data, Object> getter) {
return getter.apply(this) == null;
}
public boolean isSet(Function<Data, Object> getter) {
return !this.isNull(getter) && !this.isDefault(getter);
}
}
这里我使用了private static 属性来保存Data 的默认值,并使用3 种方法来查询任何字段状态(默认、null 或设置)。为了确定要查询哪个字段,这些方法接收一个Function<Data, Object>,给它们一个Data 实例并返回一个应该是所需字段的Object。 (如果你停下来想一想,getter 可以被视为将实例作为输入并返回实例的特定字段的函数。
所以稍后,当您需要知道某个字段是如何到达您的 JSON 输入时,只需使用这 3 种查询方法来找出:
ObjectMapper m = new ObjectMapper();
String json = "{\"field1\":null,\"field2\":20}";
Data data = m.readValue(json, Data.class);
System.out.println(data); // Data [field1=null, field2=20, field3=3.75]
System.out.println("field1 default ? " + data.isDefault(Data::getField1)); // false
System.out.println("field1 null ? " + data.isNull(Data::getField1)); // true
System.out.println("field1 set ? " + data.isSet(Data::getField1)); // false
System.out.println("field2 default ? " + data.isDefault(Data::getField2)); // false
System.out.println("field2 null ? " + data.isNull(Data::getField2)); // false
System.out.println("field2 set ? " + data.isSet(Data::getField2)); // true
System.out.println("field3 default ? " + data.isDefault(Data::getField3)); // true
System.out.println("field3 null ? " + data.isNull(Data::getField3)); // false
System.out.println("field3 set ? " + data.isSet(Data::getField3)); // false