4 回答

TA貢獻(xiàn)1827條經(jīng)驗 獲得超9個贊
什么是你的空對象?具有空值字段的對象?沒有字段的對象?您可以創(chuàng)建一個自定義來檢查節(jié)點并反序列化您想要的方式。我認(rèn)為以通用方式使用它沒有問題。
我做了一個小例子:
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貢獻(xiàn)1784條經(jīng)驗 獲得超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貢獻(xiàn)1795條經(jīng)驗 獲得超7個贊
我有同樣的問題。
我有一個City班級,有時我會收到'city':{}網(wǎng)絡(luò)服務(wù)請求。
因此,標(biāo)準(zhǔn)序列化程序創(chuàng)建一個全空字段的新城市。
我以這種方式創(chuàng)建了一個自定義反序列化器
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貢獻(xiàn)1840條經(jīng)驗 獲得超5個贊
另一種方法是使用 a com.fasterxml.jackson.databind.util.Converter<IN,OUT>,它本質(zhì)上是一個用于反序列化的后處理器。
假設(shè)我們有一個類:
public class Person {
public String id;
public String name;
}
現(xiàn)在假設(shè)我們想要將一個空的 JSON 對象{}反序列化為null, 而不是Person具有和null值的。我們可以創(chuàng)建以下內(nèi)容: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 中未給出的屬性的默認(rèn)值,而不是null.
給定轉(zhuǎn)換器,然后我們可以注釋我們的原始Person類:
@JsonDeserialize(converter=PersonConverter.class)
public class Person {
public String id;
public String name;
}
這種方法的好處是您根本不必考慮或關(guān)心反序列化;您只是在反序列化后決定如何處理反序列化的對象。您還可以使用 a 進(jìn)行許多其他轉(zhuǎn)換Converter。但這對于使“空”值無效很有效。
添加回答
舉報