问题: Jackson ObjectMapper反序列化器正在为Double字段将空值转换为0。我需要将它反序列化为null或Double.NaN。我怎样才能做到这一点?
我是否需要编写将null映射到Double.NaN的自定义Double反序列化程序?
已经尝试过:我已经搜索了DeserializationFeature枚举,但我认为没有任何内容适用。 (http://fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_NULL_FOR_PRIMITIVES)
动机:我将json对象反序列化为自定义对象(Thing),代码类似于以下内容。我需要反序列化器将值保持为null或将其更改为Double.NaN,因为我需要能够在0情况(位于纬度/经度/海拔= 0)和null / Double.NaN情况(当这些值不可用。)
杰克逊反序列化try {
ObjectMapper mapper = new ObjectMapper();
Thing t = mapper.readValue(new File("foobar/json.txt"), Thing.class);
} catch (JsonParseException e) {
...do stuff..
}
json.txt的内容。请注意,值null实际上写在文件中。它不是空的。它不是空字符串。它实际上是null。
{
"thing" : {
"longitude" : null,
"latitude" : null,
"altitude" : null
}
}
代码
import java.io.Serializable;
public class Thing implements Serializable {
private static final long serialVersionUID = 1L;
Double latitude;
Double longitude;
Double altitude;
public Thing(Double latitude, Double longitude, Double altitude) {
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
}
...rest of code...
}
答案 0 :(得分:2)
对我有用的解决方案是创建一个自定义JSON反序列化器,将null转换为Double.NaN。调整我写的内容以匹配上面的示例代码,看起来像这样。
public class ThingDeserializer extends JsonDeserializer<Thing> {
@Override
public Thing deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
Thing thingy = new Thing();
JsonNode node = jp.getCodec().readTree(jp);
if (node.get("latitude").isNull()) {
thingy.setLatitude(Double.NaN);
} else {
thingy.setLatitude(node.get("latitude").asDouble());
}
if (node.get("longitude").isNull()) {
thingy.setLongitude(Double.NaN);
} else {
thingy.setLongitude(node.get("longitude").asDouble());
}
if (node.get("altitude").isNull()) {
thingy.setAltitude(Double.NaN);
} else {
thingy.setLatitude(node.get("altitude").asDouble());
}
return thingy;
}
然后我通过在类声明上面添加注释在Thing类中注册了反序列化器。
@JsonDeserialize(using = ThingDeserializer.class)
public class Thing implements Serializable {
... class code here ...
}
注意我认为更好的答案是反序列化Double类而不是Thing类。通过反序列化Double,您可以概括从null到NaN的转换。这也将取消从字段名称中拉出节点中的特定字段。我无法弄清楚如何在有限的时间内完成这项工作,所以这对我有用。此外,反序列化实际上是由Jackson通过REST api隐式调用的,所以我不确定如何改变这些事情。我很乐意看到一个可以实现这一目标的解决方案。
答案 1 :(得分:1)
这就是我所做的:
public class DoubleDeserializer extends JsonDeserializer<Double> {
@Override
public Double deserialize(JsonParser parser, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String doubleStr = parser.getText();
if (doubleStr.isEmpty() || doubleStr == null) {
return null;
}
return new Double(doubleStr);
}
}
然后在我的bean中:
@JsonDeserialize(using = DoubleDeserializer.class)
private Double partialPressureCO2;
希望这有帮助。