49

有谁知道 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。

4

6 回答 6

114

此行为是在 Jackson 2.5.0 中引入的。您可以使用 MapperFeature 将映射器配置为不区分大小写。ACCEPT_CASE_INSENSITIVE_PROPERTIES

例如 :

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
于 2016-04-21T11:03:32.407 回答
33

如@Nicolas Riousset 所述,您可以通过配置映射器来解决此问题。

此外,从 Jackson 2.9 版本开始,您可以在@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)字段或类上使用注释来执行相同操作,这是一个更灵活的选项。

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private String firstName;
于 2019-02-26T15:07:53.867 回答
14

我有同样的问题,找不到解决这个问题的全球方法。但是,您可以为每个属性设置 2 个设置器来实现此目的:

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

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

不优雅,但适用于大写和小写 json 字段。您也可以尝试此处提到的解决方案,但这可能会产生性能开销

于 2015-02-20T19:48:17.610 回答
6
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;
            }
        }
    }

}
于 2020-03-16T21:14:13.363 回答
4

从 Jackson 2.12 版本开始,您终于可以在课堂上进行注释:

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
public class Person {
    private String firstName;
    private String lastName;
    private Date dateOfBirth;
    // setters and getters ...
}

正如Github issue中所述,仍然不支持单属性不区分大小写!

于 2020-12-10T15:59:05.820 回答
0

我处于同样的情况,不得不转换为地图,然后手动复制这些值。

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

Map<String, String> map = 
    mapper.readValue(jsonAsString, new TypeReference<Map<String, String>>(){});
于 2015-10-27T05:41:02.987 回答