Does anyone know how com.fasterxml.jackson.databind.ObjectMapper is able to map JSON properties to POJO properties case insensitive?
JSON-String:
An alternative solution is to specify JSON field names case-sensitive:
public Movie(){
//Jackson deserialize
}
@JsonProperty("Title")
public String getTitle() {
return title;
}
@JsonProperty("Year")
public String getYear() {
return year;
}
@JsonProperty("imdbID")
public String getImdbID() {
return imdbID;
}
package br.com.marcusvoltolim.util;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j;
@Log4j
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER;
static {
OBJECT_MAPPER = new ObjectMapper();
OBJECT_MAPPER.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public static <T> T fromJson(final String json, final Class<T> classe) {
try {
return OBJECT_MAPPER.readValue(json, classe);
} catch (Exception e) {
log.error(e);
try {
return classe.newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
return null;
}
}
}
}
This behaviour was introduced in Jackson 2.5.0. You can configure the mapper to be case insensitive using MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES.
For example :
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
I had the same problem and couldn't find a global way of solving this. However you can have 2 setters per property to achieve this:
@JsonSetter("FIRSTNAME")
public void setFirstNameCaps(String firstName) {
this.firstName = firstName;
}
@JsonSetter("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
Not elegant but will work for both upper and lower case json fields. You can also try the solution mentioned here but this might have a performance overhead
You can solve this problem by configuring the mapper, as described by the @Nicolas Riousset.
In addition, since version Jackson 2.9 you can do the same using annotation @JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
over a field or class, which is a more flexible option.
@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private String firstName;
I was in the same kind of situation and had to convert to a map and then copy the values over manually.
import com.fasterxml.jackson.core.type.TypeReference;
Map<String, String> map =
mapper.readValue(jsonAsString, new TypeReference<Map<String, String>>(){});