不区分大小写的JSON到POJOMap,而不更改POJO

qxgroojn  于 2022-11-26  发布在  其他
关注(0)|答案(8)|浏览(169)

有人知道com.fasterxml.jackson.databind.ObjectMapper是如何将JSON属性Map到不区分大小写的POJO属性的吗?

  • JSON字符串:*

[{“名字”:“约翰”,“姓氏”:“无名氏”,“出生日期”:“1980-07- 16 T18:25:00. 000 Z”}]

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

最后得到JsonMappingException

com.fasterxml.jackson.databind.JsonMappingException:
Can not deserialize instance of ...

JSON-String和POJO-Class都无法更改。

8ljdwjyq

8ljdwjyq1#

此行为是在Jackson2.5.0中引入的。您可以使用MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES将Map器配置为不区分大小写。
例如:

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

eyh26e7m2#

您可以通过配置Map器来解决此问题,如@Nicolas Riousset中所述。
此外,从Jackson2.9版本开始,您可以在字段或类上使用注解@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)来执行相同的操作,这是一个更灵活的选项。

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private String firstName;
ijxebb2r

ijxebb2r3#

我也遇到了同样的问题,但找不到一个全局的方法来解决这个问题。不过,你可以为每个属性设置两个setter来实现这个目标:

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

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

不太好,但是对于大小写json字段都有效。您也可以尝试here提到的解决方案,但是这可能会有性能开销

vsnjm48y

vsnjm48y4#

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

}
q9yhzks0

q9yhzks05#

从Jackson2.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中所述,仍然不支持单属性不区分大小写!

qeeaahzv

qeeaahzv6#

如果有人希望在POJO本身的字段级别处理此问题,他们可以使用以下两个注解中的任何一个

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MMM-yyyy",with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_VALUES)

或者

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MMM-yyyy",with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
2w3rbyxf

2w3rbyxf7#

第一个月

自Jackson的发行版本2.13以来,ObjectMapper.configure()方法已被弃用。

不推荐使用。从2.13开始使用JsonMapper.builder().enable(...)

建议的方法是使用configure()方法的重载版本,该方法来自MapperBuilder(* JsonMapper.Builder * 类的 * 父级)*

  • 范例:*
ObjectMapper mapper = JsonMapper.builder()
    .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
    .build();

Sping Boot -应用程序属性

在Sping Boot 应用程序中,可以通过application.properties文件(* 或 * application.yml * 文件 *)中的“公用应用程序属性”指定此自定义。

spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true

Sping Boot 会在应用程序启动时配置ObjectMapper时注意应用指定的特性(* 也通过您可以提供的属性,或打开/关闭其他与Jackson相关的属性,如默认语言环境、序列化特性等 *)。

tzxcd3kk

tzxcd3kk8#

我也遇到了同样的情况,不得不转换为Map,然后手动复制这些值。

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

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

相关问题