web-dev-qa-db-fra.com

Mappage JSON insensible à la casse vers POJO sans changer le POJO

Quelqu'un sait-il comment com.fasterxml.jackson.databind.ObjectMapper est capable de mapper les propriétés JSON aux propriétés POJO sans tenir compte de la casse?

JSON-String:

[{"FIRSTNAME": "John", "LASTNAME": "Doe", "DATEOFBIRTH": "1980-07-16T18: 25: 00.000Z"}]

Classe POJO:

public class Person {

    private String firstName;
    private String lastName;
    private Date dateOfBirth;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getDateOfBirth() {
        return dateOfBirth;
    }
    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }
}

Classe de test:

@Test
public final void testDeserializingPersonJsonToPersonClass()
        throws JsonParseException, JsonMappingException, IOException {
    final String jsonAsString = "[{\"FIRSTNAME\":\"John\",\"LASTNAME\":\"Doe\",\"DATEOFBIRTH\":\"1980-07-16T18:25:00.000Z\"}]";
    final ObjectMapper mapper = new ObjectMapper();

    final Person person = mapper.readValue(jsonAsString, Person.class);

    assertNotNull(person);
    assertThat(person.getFirstName(), equalTo("John"));
}

Cela se termine par l'erreur suivante:
com.fasterxml.jackson.databind.JsonMappingException: impossible de désérialiser l'instance de ...

Il n'est pas possible de modifier ni JSON-String ni POJO-Class.

28
Mark Fellner

Ce comportement a été introduit dans Jackson 2.5.0. Vous pouvez configurer le mappeur pour qu'il soit insensible à la casse en utilisant MapperFeature . ACCEPT_CASE_INSENSITIVE_PROPERTIES .

Par exemple :

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
54
Nicolas Riousset

J'ai eu le même problème et je n'ai pas pu trouver un moyen global de résoudre ce problème. Cependant, vous pouvez avoir 2 setters par propriété pour y parvenir:

@JsonSetter("FIRSTNAME")
public void setFirstNameCaps(String firstName) {
    this.firstName = firstName;
}

@JsonSetter("firstName")
public void setFirstName(String firstName) {
    this.firstName = firstName;
}

Pas élégant mais fonctionnera pour les champs json majuscules et minuscules. Vous pouvez également essayer la solution mentionnée ici mais cela pourrait avoir une surcharge de performances

9
Dhananjay

Vous pouvez résoudre ce problème en configurant le mappeur, comme décrit par le @Nicolas Riousset.

De plus, depuis la version Jackson 2.9, vous pouvez faire de même en utilisant l'annotation @JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) sur un champ ou une classe, ce qui est une option plus flexible.

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private String firstName;
3
Dmitry Kokora

J'étais dans le même genre de situation et j'ai dû convertir en une carte, puis copier manuellement les valeurs.

import com.fasterxml.jackson.core.type.TypeReference;

Map<String, String> map = 
    mapper.readValue(jsonAsString, new TypeReference<Map<String, String>>(){});
0
Harry Glasgow