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

时间:2014-09-26 11:48:42

标签: java json data-binding case-insensitive fasterxml

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

JSON字符串:

  

[{" FIRSTNAME":"约翰"" LASTNAME":" Doe的"" DATEOFBIRTH&#34 ;: " 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。

7 个答案:

答案 0 :(得分:49)

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

例如:

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

答案 1 :(得分:7)

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

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

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

不优雅,但适用于大小写json字段。您也可以尝试提及here的解决方案,但这可能会带来性能开销

答案 2 :(得分:3)

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

}

答案 3 :(得分:1)

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

此外,自杰克逊2.9版起,您可以在字段或类上使用注释@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)来进行相同的操作,这是一种更加灵活的选择。

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

答案 4 :(得分:0)

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

<input
      date-range-picker
      type="text"
      ng-model="scheduledDate"
      options="{timePicker: true, timePickerIncrement:30,locale: {format: 'DD/MM/YYYY hh:mm:ss'},separator: '-'}"
/>


$scope.scheduledDate = {startDate:new Date(myDateTime),endDate:new Date(myDateTime)}

答案 5 :(得分:0)

从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 :(得分:-1)

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

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

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