不改变 POJO 的不区分大小写的 JSON 到 POJO 的映射
Posted
技术标签:
【中文标题】不改变 POJO 的不区分大小写的 JSON 到 POJO 的映射【英文标题】:Case insensitive JSON to POJO mapping without changing the POJO 【发布时间】:2014-11-21 10:09:23 【问题描述】:有谁知道 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。
【问题讨论】:
既不能改变JSON-String也不能改变POJO-Class,那就不可能了。 【参考方案1】:此行为是在 Jackson 2.5.0 中引入的。您可以使用 MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES 将映射器配置为不区分大小写。
例如:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
【讨论】:
【参考方案2】:如@Nicolas Riousset 所述,您可以通过配置映射器来解决此问题。
此外,从 Jackson 2.9 版本开始,您可以在字段或类上使用注解 @JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
执行相同操作,这是一种更灵活的选择。
@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
private String firstName;
【讨论】:
我在至少使用 jackson 2.9 的 Spring Boot 应用程序中进行了尝试,但似乎没有帮助。我的用例不同吗?我乐观地认为有解决方案,但我还没有找到任何东西......我想相信:) @user1445967,您如何使用此功能?您还有其他 Jackson 映射配置吗? 我说的是 Spring [Boot] MVC 中的“普通”@RequestMapping / @GetMapping / @PostMapping
,其中 @RequestBody
注释放置在用于存储 JSON 属性的对象之前。出于这个原因,我们不会(故意)尝试配置 Jackson 的任何部分...
自 2020 年 5 月起,您不能在课程级别应用此映射器功能。此类功能仍未实现。目前预定 Jackson 2.12 版github.com/FasterXML/jackson-databind/issues/1886
不,该示例不起作用。注释仅适用于被注释元素对象中的属性,而不适用于被注释属性本身。没有单一属性不区分大小写!【参考方案3】:
我遇到了同样的问题,但找不到解决此问题的全局方法。但是,您可以为每个属性设置 2 个设置器来实现此目的:
@JsonSetter("FIRSTNAME")
public void setFirstNameCaps(String firstName)
this.firstName = firstName;
@JsonSetter("firstName")
public void setFirstName(String firstName)
this.firstName = firstName;
不优雅,但适用于大小写 json 字段。您也可以尝试here 提到的解决方案,但这可能会产生性能开销
【讨论】:
【参考方案4】: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;
【讨论】:
【参考方案5】:从 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 中所述,仍然不支持单属性不区分大小写!
【讨论】:
【参考方案6】:我遇到了同样的情况,不得不转换为地图,然后手动复制这些值。
import com.fasterxml.jackson.core.type.TypeReference;
Map<String, String> map =
mapper.readValue(jsonAsString, new TypeReference<Map<String, String>>());
【讨论】:
以上是关于不改变 POJO 的不区分大小写的 JSON 到 POJO 的映射的主要内容,如果未能解决你的问题,请参考以下文章
区分 json 中不存在字段的时间和将其值作为 null 发送的时间
使用 Hibernate Criteria 的不区分大小写的排序
nvarchar 类型的不区分大小写的主键,其中 ß != ss