4 回答
TA贡献1827条经验 获得超9个赞
什么是你的空对象?具有空值字段的对象?没有字段的对象?您可以创建一个自定义来检查节点并反序列化您想要的方式。我认为以通用方式使用它没有问题。
我做了一个小例子:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.Objects;
public class DeserializerExample<T> extends StdDeserializer<T> {
private final ObjectMapper defaultMapper;
public DeserializerExample(Class<T> clazz) {
super(clazz);
defaultMapper = new ObjectMapper();
}
@Override
public T deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
System.out.println("Deserializing...");
JsonNode node = jp.getCodec().readTree(jp);
for (JsonNode jsonNode : node) {
if (!jsonNode.isNull()) {
return defaultMapper.treeToValue(node, (Class<T>) getValueClass());
}
}
return null;
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Person.class, new DeserializerExample(Person.class));
mapper.registerModule(module);
Person person = mapper.readValue("{\"id\":1, \"name\":\"Joseph\"}", Person.class);
Person nullPerson = mapper.readValue("{\"id\":null, \"name\":null}", Person.class);
System.out.println("Is null: " + Objects.isNull(person));
System.out.println("Is null: " + Objects.isNull(nullPerson));
}
}
TA贡献1784条经验 获得超7个赞
唯一的方法是使用自定义解串器:
class CustomDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.readValueAsTree();
if (node.asText().isEmpty()) {
return null;
}
return node.toString();
}
}
然后做:
class EventBean {
public Long eventId;
public String title;
@JsonDeserialize(using = CustomDeserializer.class)
public String location;
}
TA贡献1795条经验 获得超7个赞
我有同样的问题。
我有一个City班级,有时我会收到'city':{}网络服务请求。
因此,标准序列化程序创建一个全空字段的新城市。
我以这种方式创建了一个自定义反序列化器
public class CityJsonDeSerializer extends StdDeserializer<City> {
@Override
public City deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
if(node.isNull() || node.asText().isEmpty()|| node.size()==0)
return null;
City city = new City();
... // set all fields
return city;
}
}
if 检查条件:
'city' : null
'city' : ''
'city' : '{}'
如果为真,反序列化器返回null
.
TA贡献1840条经验 获得超5个赞
另一种方法是使用 a com.fasterxml.jackson.databind.util.Converter<IN,OUT>,它本质上是一个用于反序列化的后处理器。
假设我们有一个类:
public class Person {
public String id;
public String name;
}
现在假设我们想要将一个空的 JSON 对象{}反序列化为null, 而不是Person具有和null值的。我们可以创建以下内容:idnameConverter
public PersonConverter implements Converter<Person,Person> {
@Override
public Person convert(Person p) {
return isEmpty(p) ? null : value;
}
private static boolean isEmpty(Person p) {
if(p == null) {
return true;
}
if(Optional.ofNullable(p.id).orElse("").isEmpty() &&
Optional.ofNullable(p.name).orElse("").isEmpty()) {
return true;
}
return false;
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return typeFactory.constructType(Person.class);
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return typeFactory.constructType(Person.class);
}
}
请注意,我们必须处理空白String情况,因为这是(违反直觉)分配给 JSON 中未给出的属性的默认值,而不是null.
给定转换器,然后我们可以注释我们的原始Person类:
@JsonDeserialize(converter=PersonConverter.class)
public class Person {
public String id;
public String name;
}
这种方法的好处是您根本不必考虑或关心反序列化;您只是在反序列化后决定如何处理反序列化的对象。您还可以使用 a 进行许多其他转换Converter。但这对于使“空”值无效很有效。
添加回答
举报