Konstantinos Raptis
Konstantinos Raptis

Reputation: 149

Use Jackson to deserialize JSON string or object into a String field

I am using Jackson 2 library and I am trying to read a JSON response, which looks like:

{ "value":"Hello" }

When value is empty, JSON response looks like:

{ "value":{} }

My model POJO class looks like this

public class Hello {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

The problem is that when response looks like {value:{}}, Jackson is trying to read an Object, but my model class field is a string, so it throws an Exception:

JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token. 

My question is how Jackson can successfully read JSONs who look like:

 {"value":"something"} 

and at the same time if response looks like this {"value":{}} (empty response for me), pass null to value field of my Hello model class.

I am using the code below in order to read JSON string:

String myJsonAsString = "{...}";
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(myJsonAsString , Hello.class);

Upvotes: 6

Views: 13867

Answers (2)

Alexander
Alexander

Reputation: 21

Txh for JB Nizet, but if you get type another than String (e.g Object), Jackson deserialiser tried to deserialize inner Object and can throw a latent exception. After that, other fields in json filled as null in Java.

To avoid this you'll ignore children

@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    JsonToken jsonToken = p.currentToken();
    if (jsonToken == JsonToken.VALUE_STRING) {
        return p.getValueAsString();
    }
    p.skipChildren();
    return "other_string";
}

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691635

You can use a custom deserializer for this feld. Here is one that returns the string if it's there, or null in any other case:

public class Hello {

    @JsonDeserialize(using = StupidValueDeserializer.class)
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

public class StupidValueDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonToken jsonToken = p.getCurrentToken();
        if (jsonToken == JsonToken.VALUE_STRING) {
            return p.getValueAsString();
        }
        return null;
    }
}

Upvotes: 14

Related Questions