I have a webservice which prints "null" as a string for any property instead of null literal. It does that for almost all data types(String or Date). For example, in ideal case it returns
{
"item" : {
"title": "Some title",
"expires": "2014-11-02 00:00:00"
}
}
But sometimes it returns:
{
"item" : {
"title": "null",
"expires": "2014-11-02 00:00:00"
}
}
Which makes the title property value as "null" instead of setting it to null. Or sometime this:
{
"item" : {
"title": "Some title",
"expires": "null"
}
}
Which makes the deserialization fail because the dateformat does not match. How can I configure objectmapper or annotate my model classes to resolve these problems during deserialization?
My model class looks like:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Item {
public String title;
@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
public Date expires;
}
It's an android app so I have no control over the webservice. Thanks in advance
Serialize Null Fields Fields/PropertiesWith its default settings, Jackson serializes null-valued public fields. In other words, resulting JSON will include null fields. Here, the name field which is null is in the resulting JSON string.
Jackson default include null fields 1.2 By default, Jackson will include the null fields. To ignore the null fields, put @JsonInclude on class level or field level.
To ignore Null fields in JSON, Jackson provides Include. NON_NULL and to ignore Empty fields Jackson provides Include. NON_EMPTY .
This short tutorial shows how the Jackson library can be used to serialize Java object to XML and deserialize them back to objects.
Since someone asked this question again a few minutes ago, I did some research and think I found a good solution to this problem (when dealing with Strings).
You have to create a custom JsonDeserializer class as follows:
class NullStringJsonDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String result = StringDeserializer.instance.deserialize(p, ctxt);
return result!=null && result.toLowerCase().equals(null+"") ? null : result;
}
}
Last but not least, all you have to do is tell your ObjectMapper that it should use your custom json string deserializer. This depends on how and where you use your ObjectMapper but could look like that:
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new NullStringJsonDeserializer());
objectMapper.registerModule(module);
If you use a custom Deserializer
, you can do this, but I don't think it's available using standard annotations.
Borrowing and modifying some code from http://www.baeldung.com/jackson-deserialization :
public class ItemDeserializer extends JsonDeserializer<Item> {
@Override
public Item deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
String title = null;
TextNode titleNode = (TextNode)node.get("title");
if ( ! titleNode.toString().equals("null")) {
title = titleNode.toString();
}
Date expires = null;
// similar logic for expires
return new Item(title, expires);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With