Java 不更改 POJO 的不区分大小写的 JSON 到 POJO 映射

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26058854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:46:26  来源:igfitidea点击:

Case insensitive JSON to POJO mapping without changing the POJO

javajsondata-bindingcase-insensitivefasterxml

提问by Mark Fellner

Does anyone know how com.fasterxml.Hymanson.databind.ObjectMapper is able to map JSON properties to POJO properties case insensitive?

有谁知道 com.fasterxml.Hymanson.databind.ObjectMapper 如何能够将 JSON 属性映射到不区分大小写的 POJO 属性?

JSON-String:

JSON 字符串:

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

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

POJO-Class:

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-Class:

测试类:

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

This ends up in following error:
com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of ...

这最终会出现以下错误:
com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of ...

It's not possible to change neither JSON-String nor POJO-Class.

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

回答by Dhananjay

I had the same problem and couldn't find a global way of solving this. However you can have 2 setters per property to achieve this:

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

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

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

Not elegant but will work for both upper and lower case json fields. You can also try the solution mentioned herebut this might have a performance overhead

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

回答by Harry Glasgow

I was in the same kind of situation and had to convert to a map and then copy the values over manually.

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

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

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

回答by Nicolas Riousset

This behaviour was introduced in Hymanson 2.5.0. You can configure the mapper to be case insensitive using MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES.

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

For example :

例如 :

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

回答by Dmitry Kokora

You can solve this problem by configuring the mapper, as described by the @Nicolas Riousset.

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

In addition, since version Hymanson 2.9 you can do the same using annotation @JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)over a field or class, which is a more flexible option.

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

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

回答by jmojico

An alternative solution is to specify JSON field names case-sensitive:

另一种解决方案是指定 JSON 字段名称区分大小写:

public Movie(){
    //Hymanson deserialize
}
@JsonProperty("Title")
public String getTitle() {
    return title;
}

@JsonProperty("Year")
public String getYear() {
    return year;
}
@JsonProperty("imdbID")
public String getImdbID() {
    return imdbID;
}

回答by Marcus Vinícius Voltolim

package br.com.marcusvoltolim.util;


import com.fasterxml.Hymanson.databind.DeserializationFeature;
import com.fasterxml.Hymanson.databind.MapperFeature;
import com.fasterxml.Hymanson.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;
            }
        }
    }

}