I am trying a simple JSON to de-serialize in to java object. I am however, getting empty String values for java.lang.String
property values. In rest of
Jackson will give you null for other objects, but for String it will give empty String.
But you can use a Custom JsonDeserializer
to do this:
class CustomDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.readValueAsTree();
if (node.asText().isEmpty()) {
return null;
}
return node.toString();
}
}
In class you have to use it for location field:
class EventBean {
public Long eventId;
public String title;
@JsonDeserialize(using = CustomDeserializer.class)
public String location;
}
I could get this by following configuration.
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
It is possible to define a custom deserializer for the String type, overriding the standard String deserializer:
this.mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new StdDeserializer<String>(String.class) {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String result = StringDeserializer.instance.deserialize(p, ctxt);
if (StringUtils.isEmpty(result)) {
return null;
}
return result;
}
});
mapper.registerModule(module);
This way all String fields will behave the same way.
it is possible to use JsonCreator annotation. It worked for me
public class Foo {
private String field;
@JsonCreator
public Foo(
@JsonProrerty("field") String field) {
this.field = StringUtils.EMPTY.equals(field) ? null : field ;
}
}
A simple work around would be to replace "" with null before deserializing the json string.
.replace("\"\"", "null")
This way all blank string will be deserialized as null
You might first like to see if there has been any progress on the Github issue requesting this exact feature.
For those using Spring Boot: The answer from jgesser was the most helpful to me, but I spent a while trying to work out the best way to configure it in Spring Boot.
Actually, the documentation says:
Any beans of type com.fasterxml.jackson.databind.Module are automatically registered with the auto-configured Jackson2ObjectMapperBuilder and are applied to any ObjectMapper instances that it creates.
So here's jgesser's answer expanded into something you can copy-paste into a new class in a Spring Boot application
@Configuration
public class EmptyStringAsNullJacksonConfiguration {
@Bean
SimpleModule emptyStringAsNullModule() {
SimpleModule module = new SimpleModule();
module.addDeserializer(
String.class,
new StdDeserializer<String>(String.class) {
@Override
public String deserialize(JsonParser parser, DeserializationContext context)
throws IOException {
String result = StringDeserializer.instance.deserialize(parser, context);
if (StringUtils.isEmpty(result)) {
return null;
}
return result;
}
});
return module;
}
}