web-dev-qa-db-ja.com

POJOを変更せずに、大文字と小文字を区別しないJSONからPOJOへのマッピング

Com.fasterxml.jackson.databind.ObjectMapperがJSONプロパティを大文字と小文字を区別しないPOJOプロパティにマップする方法を知っている人はいますか?

JSON文字列:

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

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;
    }
}

テストクラス:

@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"));
}

これにより、次のエラーが発生します。
com.fasterxml.jackson.databind.JsonMappingException:のインスタンスをデシリアライズできません...

JSON-StringもPOJO-Classも変更することはできません。

28
Mark Fellner

この動作はJackson 2.5.0で導入されました。 MapperFeatureを使用して、大文字と小文字を区別しないようにマッパーを構成できます。 ACCEPT_CASE_INSENSITIVE_PROPERTIES

例えば ​​:

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

私は同じ問題を抱えており、これを解決するグローバルな方法を見つけることができませんでした。ただし、これを実現するためにプロパティごとに2つのセッターを持つことができます。

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

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

エレガントではありませんが、大文字と小文字の両方のjsonフィールドで機能します。上記の解決策を試すこともできます here しかし、これはパフォーマンスのオーバーヘッドがあるかもしれません

9
Dhananjay

@Nicolas Rioussetで説明されているように、マッパーを構成することでこの問題を解決できます。

さらに、バージョンJackson 2.9以降では、フィールドまたはクラスに対して注釈@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)を使用して同じことができます。これはより柔軟なオプションです。

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

私は同じような状況にあり、マップに変換してから手動で値をコピーする必要がありました。

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

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