Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore empty string as null during deserialization

I try to deserialize the following json into a java pojo.

[{
    "image" : {
        "url" : "http://foo.bar"
    }
}, {
    "image" : ""      <-- This is some funky null replacement
}, {
    "image" : null    <-- This is the expected null value (Never happens in that API for images though)
}]

And my Java classes looks like this:

public class Server {

    public Image image;
    // lots of other attributes

}

and

public class Image {

    public String url;
    // few other attributes

}

I use jackson 2.8.6

ObjectMapper.read(json, LIST_OF_SERVER_TYPE_REFERENCE);

but i keep getting the following exception:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of Image: no String-argument constructor/factory method to deserialize from String value ('')

If I add a String setter for it

public void setImage(Image image) {
    this.image = image;
}

public void setImage(String value) {
    // Ignore
}

I get the following exception

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token

The exception does not change whether or not I (also) add a Image setter or not.

I also tried @JsonInclude(NOT_EMPTY) but this only seems to affect the serialization.

Summary: Some (badly designed) API sends me an empty string ("") instead of null and I have to tell Jackson to just ignore that bad value. How can I do this?

like image 920
ST-DDT Avatar asked Apr 11 '17 15:04

ST-DDT


People also ask

How do I ignore empty values in JSON response?

You can ignore null fields at the class level by using @JsonInclude(Include. NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null. You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null.

How do you tell Jackson to ignore a field during Deserialization if its value is null?

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.

Is empty string nil?

An empty string is a String object with an assigned value, but its length is equal to zero. A null string has no value at all.

What does JsonInclude include Non_null mean?

Include. NON_NULL: Indicates that only properties with not null values will be included in JSON. Include. NON_EMPTY: Indicates that only properties that are not empty will be included in JSON. Non-empty can have different meaning for different objects such as List with size zero will be considered as empty.


1 Answers

There doesn't seem to be a outof the box solution, so i went for the custom deserializer one:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

public class ImageDeserializer extends JsonDeserializer<Image> {

    @Override
    public Image deserialize(final JsonParser parser, final DeserializationContext context)
            throws IOException, JsonProcessingException {
        final JsonToken type = parser.currentToken();
        switch (type) {
            case VALUE_NULL:
                return null;
            case VALUE_STRING:
                return null; // TODO: Should check whether it is empty
            case START_OBJECT:
                return context.readValue(parser, Image.class);
            default:
                throw new IllegalArgumentException("Unsupported JsonToken type: " + type);
        }
    }

}

And use it using the following code

@JsonDeserialize(using = ImageDeserializer.class)
@JsonProperty("image")
public Image image;
like image 162
ST-DDT Avatar answered Sep 22 '22 21:09

ST-DDT