Handling N / A as Null with Jackson

I am receiving data from external JSON API and parse the result using Jackson. Unfortunately, this API returns all fields as String

, and they are populated with "N/A"

when no data is available.

I would like to replace those fields null

, especially since it is frustrating when I am trying to convert JSON String fields to more informative Java fields.

Custom DeserializationProblemHandler

worked for fields Integer

(see below), but it was not used for Java 8 fields LocalDate

. In addition, he reacts to the problem, rather than anticipating it.

I was unable to find a pre-processor to set up in mine ObjectMapper

and am embarrassed with the idea of ​​overriding BeanDeserializer

.

Do you know the best / cleanest solution for dealing with situations like this? Thank!


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 while processing "N/A"

in the fieldLocalDate

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

      

(works great when there is a date in the data)

+3


source to share


1 answer


I feel like there must be a better way to do this, but the following is the only solution I could come up with.

Create a new JsonDeserializer

one that handles the "N / A" input. The following example processes 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 the ObjectMapper

following:

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

      

You probably want to bundle all of your converters into a module named API that forces you to handle things like this.

+1


source







All Articles