Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treating "N/A" value as null with Jackson

Tags:

java

json

jackson

I am getting data from an external JSON API and parsing the result with Jackson. Unfortunately, that API returns all fields as String and those are filled with "N/A" when data is unavailable.

I would like to replace those fields with null, especially as those are frustrating when I try to convert JSON String fields to more informative Java fields.

A custom DeserializationProblemHandler worked for Integer fields (see below), but it was useless for Java 8's LocalDate fields. Furthermore, it reacts to a problem rather than anticipating it.

I was unable to find a pre-processor to configure into my ObjectMapper and am uneasy with the idea of overriding the BeanDeserializer.

Do you know of a better/cleaner solution to handle this kind of situations? Thanks!


DeserializationProblemHandler

new DeserializationProblemHandler() {
    @Override
    public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert, String failureMsg) throws IOException {
        return "N/A".equals(valueToConvert) ? null : super.handleWeirdStringValue(ctxt, targetType, valueToConvert, failureMsg);
    }
}

Error message when processing "N/A" in LocalDate field

Can not deserialize value of type java.time.LocalDate from String "N/A": Text 'N/A' could not be parsed at index 0

(works fine when there is date in the data)

like image 685
Chop Avatar asked May 14 '17 13:05

Chop


People also ask

How does Jackson serialize null?

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.

How do I ignore null values in Jackson?

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.

What is JSON mapping exception?

public class JsonMappingException extends JsonProcessingException. Checked exception used to signal fatal problems with mapping of content, distinct from low-level I/O problems (signaled using simple IOException s) or data encoding/decoding problems (signaled with JsonParseException , JsonGenerationException ).


1 Answers

I feel like there ought to be a better way of doing this, but the following is the only solution I was able to come up with.

Create a new JsonDeserializer that handles "N/A" input. The following example handles strings:

public class EmptyStringDeserializer extends StdScalarDeserializer<String> {
    public EmptyStringDeserializer() {
        super(String.class);
    }

    @Override
    public String deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        final String val = parser.getValueAsString();

        if ("N/A".equalsIgnoreCase(val))
            return null;

        return val;
    }
}

The class is registered with an ObjectMapper like this:

SimpleModule simpleModule = new SimpleModule().addDeserializer(String.class, new EmptyStringDeserializer());
ObjectMapper om = new ObjectMapper().registerModule(simpleModule);

You'll probably want to collect all your converters in a module named for the API that is making you handle things this way.

like image 123
Henrik Aasted Sørensen Avatar answered Oct 24 '22 07:10

Henrik Aasted Sørensen