我正在解析输入的 JSON。对于一个字段,有 3 种可能性:
- 该字段不存在;
- 该值设置为空;
- 该值设置为有效值。
实现了不同的行为:对于 JSON 中不存在的值,将默认值插入到数据库中;对于 JSON 中的空值,将空值插入到数据库中。
我考虑过可选
来对此建模:
public class Data {
private Optional<String> field;
}
以下两个选项中哪个最有意义?
- 如果
field
为 null,则该字段在 JSON 中不存在。如果field
为 Optional.empty,则该字段在 JSON 中为null
。 - 如果
field
为 null,则该字段在 JSON 中为null
。如果field
为 Optional.empty,则该字段在 JSON 中不存在。
FWIW,我使用带有模块 jackson-datatype-jdk8 的 Jackson 来解析输入的 JSON。
最佳答案
我认为你不应该使用 Optional
对于这种情况。正如@dkatzel 在他的回答中提到的,它更应该用作 API 返回值而不是字段。
尽管进行了这种学术讨论,但您可以通过初始化 Data
中的字段来简单地完成您想要的。类的默认值:
public class Data {
private String field = DEFAULT_VALUE;
}
然后让 Jackson 完成剩下的工作。
根据 OP 的评论进行编辑:
当您的 JSON 带有 null
时field
的值, Jackson 会将其设置为 null
,这就是将存储在数据库中的内容。
当您的 JSON 不包含该字段时,DEFAULT_VALUE
将自动加载到您的 Data
中实例。
当您的 JSON 实际上包含 field
的值时, Jackson 将设置它,该值将到达数据库。
编辑 2,考虑到 OP 要求查明 field
是否存在要么被填写,设置为null
或者在解析 JSON 输入后在输入 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 种方法来查询任何字段状态(默认、空或设置)。为了确定要查询的字段,这些方法会收到一个 Function<Data, Object>
。 , 给定一个 Data
实例并返回 Object
那应该是所需的字段。 (如果你停止思考,getters 可以看作是将实例作为输入并返回实例的特定字段的函数)。
所以稍后,当您需要知道某个字段如何到达您的 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
关于java8 - 缺少变量和可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31456327/