[英]How to deserialize null type JSON fields with Jackson
I'm developing a PATCH API. 我正在开发PATCH API。 If the fields are sent as JSON
null
value I need to save them as null
. 如果字段以JSON
null
值发送,则需要将它们另存为null
。 However I can't distinguish if they're sent as null
or never sent. 但是我无法区分它们是作为null
发送还是从不发送。
{
"max_amount": null
}
Double maxAmount;
I have Double
, Integer
, Date
etc. fields. 我有Double
, Integer
, Date
等字段。 I can deserialize them to Double.NAN
, Integer.MIN_VALUE
when they're really sent as null
to understand if they're sent as null
. 我可以在将它们真正发送为null
时将它们反序列化为Double.NAN
, Integer.MIN_VALUE
,以了解是否将它们发送为null
。 But Deserializers don't work when the field is null
. 但是,当字段为null
时,反序列化器将不起作用。 Of course it's an option to send "-1" or an impossible value to define null
but I didn't like this approach. 当然,可以选择发送“ -1”或一个不可能的值来定义null
但我不喜欢这种方法。 I will have to agree with the clients for all types. 我将不得不同意所有类型的客户。 What's the best approach in this case? 在这种情况下最好的方法是什么?
In cases like this you should define POJO
class with properties set to predefined undefined like
data. 在这种情况下,您应该定义POJO
类,并将其属性设置为预定义的undefined like
数据。 For example, for Integer
property if negative numbers are not allowed from business point of view, it could be -1
. 例如,对于Integer
属性,如果从业务角度来看不允许使用负数,则它可以是-1
。 Then, when JSON
is deserialised to POJO
properties set to null
override default values and you will know it was sent. 然后,当将JSON
反序列化为POJO
属性设置为null
会覆盖默认值,并且您将知道它已发送。 There should be 3 options: 应该有3个选择:
JSON
- properly deserialised to a value in POJO
JSON
常规值-正确反序列化为POJO
的值 null
value in JSON
- deserialised to null
in POJO
JSON
null
值-在POJO
反序列化为null
key-value
- default value in POJO
is not overridden. 不可用对key-value
POJO
默认值不会被覆盖。 Below example uses Jackson
in version 2.9.9
: 下面的示例在2.9.9
版中使用Jackson
:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDateTime;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
String[] jsons = {
"{\"number\":1,\"date\":\"2019-01-01T22:23:11\",\"max_amount\":4.9}",
"{\"number\":null,\"date\":null,\"max_amount\":null}",
"{}",
"{\"number\":1}",
"{\"date\":\"2019-01-01T22:23:11\"}",
"{\"max_amount\":4.9}",
"{\"number\":1,\"date\":null,\"max_amount\":null}"
};
for (String json : jsons) {
System.out.println(json + " => " + mapper.readValue(json, Pojo.class));
}
}
}
class Pojo {
private static final LocalDateTime NULL_DATE = LocalDateTime.of(1900, 1, 1, 12, 13);
@JsonProperty("max_amount")
private Double maxAmount = Double.MIN_VALUE;
private Integer number = Integer.MIN_VALUE;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private LocalDateTime date = NULL_DATE;
public Double getMaxAmount() {
return maxAmount;
}
public void setMaxAmount(Double maxAmount) {
this.maxAmount = maxAmount;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
@Override
public String toString() {
return "{" +
"number=" + number +
", date=" + date +
", maxAmount=" + maxAmount +
'}';
}
}
Above code prints: 上面的代码打印:
{"number":1,"date":"2019-01-01T22:23:11","max_amount":4.9} => {number=1, date=2019-01-01T22:23:11, maxAmount=4.9}
{"number":null,"date":null,"max_amount":null} => {number=null, date=null, maxAmount=null}
{} => {number=-2147483648, date=1900-01-01T12:13, maxAmount=4.9E-324}
{"number":1} => {number=1, date=1900-01-01T12:13, maxAmount=4.9E-324}
{"date":"2019-01-01T22:23:11"} => {number=-2147483648, date=2019-01-01T22:23:11, maxAmount=4.9E-324}
{"max_amount":4.9} => {number=-2147483648, date=1900-01-01T12:13, maxAmount=4.9}
{"number":1,"date":null,"max_amount":null} => {number=1, date=null, maxAmount=null}
Of course, you should pick default values in the way it will minimise possibility of collision that client by accident send value treated as undefined
by your API
. 当然,您应该选择默认值,以最大程度地减少客户端偶然发送的值被API
undefined
的冲突可能性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.