为什么杰克逊在不同情况下将这些值映射两次?

时间:2015-05-05 19:57:26

标签: java json jackson

我使用Jackson将Java对象映射到JSON,该对象是一个非常简单的pojo类,如下所示:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonAutoDetect
public class Area {
    @JsonProperty("Id")
    public int Id;
    @JsonProperty("Name")
    public String Name;

    public Area() {
        Name = "";
    }

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String Name) {
        this.Name = Name;
    }
}

映射代码如下所示:

ObjectMapper mapper = new ObjectMapper();

mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
            .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
            .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
            .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

areaJSON = mapper.writeValueAsString(area);

但此时areaJSON的值如下:

{"id":0,"name":"","Name":"","Id":0}

请注意具有不同情况的多个值。

我做错了什么?

4 个答案:

答案 0 :(得分:12)

杰克逊认为字段IdName与getter返回的字段不同,因为案例不同。使用标准JavaBeans命名约定,Jackson推断对应于getter的字段名为idname,而不是IdName

案件很重要。

有两种简单的方法可以解决这个问题:

  1. 完全从此课程中删除@JsonAutoDetect注释。我非常确定默认注释值优先于ObjectMapper的配置。交替:

  2. 根本不要使用ObjectMapper。将班级的@JsonAutoDetect更改为

    @JsonAutoDetect(
      fieldVisibility = Visibility.ANY,
      getterVisibility = Visibility.NONE,
      setterVisibility = Visibility.NONE,
      creatorVisibility = Visibility.NONE
    )
    

答案 1 :(得分:1)

您需要使用@JsonProperty(“Id”)注释getId方法,否则getId也将添加小写ID。

答案 2 :(得分:0)

我知道这是一个旧帖子,但有一个更简单的解决方案: 仅对字段使用注释:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Area {
   public int id;
   public String name;

   public Area() {
     name = "";
   }

   public int getId() {
    return id;
   }

   public void setId(int id) {
     id = id;
   }

   public String getName() {
     return name;
   }

   public void setName(String Name) {
     this.name = Name;
   }
}

您可以选择序列化对象的方式:使用字段或使用属性。如果使用这些字段,则会忽略getter和setter。

代码中的问题是由首字母大写创建的:访问字段,json属性为Id;访问getter,getId变为id(get后的第一个字母以小写编码)。

答案 3 :(得分:0)

我的解决方案是将注释移动到 setter 或 getter(两者都可以)