Solución:
Jackson le dará un valor nulo para otros objetos, pero para String dará un String vacío.
Pero puedes usar un Custom JsonDeserializer
para hacer esto:
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();
}
}
En clase tienes que usarlo para el campo de ubicación:
class EventBean {
public Long eventId;
public String title;
@JsonDeserialize(using = CustomDeserializer.class)
public String location;
}
Es posible definir un deserializador personalizado para el tipo de cadena, anulando el deserializador de cadena estándar:
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);
De esta manera, todos los campos de cadena se comportarán de la misma manera.
Es posible que primero desee ver si ha habido algún progreso en el problema de Github al solicitar esta característica exacta.
Para aquellos que usan Spring Boot: La respuesta de jgesser fue la más útil para mí, pero pasé un tiempo tratando de encontrar la mejor manera de configurarlo en Spring Boot.
En realidad, la documentación dice:
Todos los beans de tipo com.fasterxml.jackson.databind.Module se registran automáticamente con el Jackson2ObjectMapperBuilder autoconfigurado y se aplican a cualquier instancia de ObjectMapper que cree.
Entonces, aquí está la respuesta de jgesser expandida en algo que puede copiar y pegar en una nueva clase en una aplicación Spring Boot
@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;
}
}