为什么 Jackson 在不同的情况下两次映射这些值?
Why is Jackson mapping these values twice, in differing case?
我正在使用 Jackson 将 Java 对象映射到 JSON,该对象是一个非常简单的 pojo class,如下所示:
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}
注意大小写不同的多个值。
我做错了什么?
Jackson 认为 Id
和 Name
字段与 getter 返回的字段是不同的属性,因为大小写不同。使用标准的 JavaBeans 命名约定,Jackson 推断对应于 getter 的字段被命名为 id
和 name
,而不是 Id
和 Name
.
tl;dr 案件很重要。
有两种简单的方法可以解决这个问题:
从 class 中完全删除 @JsonAutoDetect
注释。我很确定默认注释值优先于 ObjectMapper
的配置。或者:
根本不要乱用 ObjectMapper
。将 class 上的 @JsonAutoDetect
更改为
@JsonAutoDetect(
fieldVisibility = Visibility.ANY,
getterVisibility = Visibility.NONE,
setterVisibility = Visibility.NONE,
creatorVisibility = Visibility.NONE
)
getId方法需要注解@JsonProperty("Id"),否则getId也会加上小写的id。
我知道这是一个旧的 post,但有一个更简单的解决方案:
仅在字段上使用注释:
@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 后的第一个字母被编码为小写)。
我的解决方案是将注释移动到 setter 或 getter(两者都可以)
我正在使用 Jackson 将 Java 对象映射到 JSON,该对象是一个非常简单的 pojo class,如下所示:
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}
注意大小写不同的多个值。
我做错了什么?
Jackson 认为 Id
和 Name
字段与 getter 返回的字段是不同的属性,因为大小写不同。使用标准的 JavaBeans 命名约定,Jackson 推断对应于 getter 的字段被命名为 id
和 name
,而不是 Id
和 Name
.
tl;dr 案件很重要。
有两种简单的方法可以解决这个问题:
从 class 中完全删除
@JsonAutoDetect
注释。我很确定默认注释值优先于ObjectMapper
的配置。或者:根本不要乱用
ObjectMapper
。将 class 上的@JsonAutoDetect
更改为@JsonAutoDetect( fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, creatorVisibility = Visibility.NONE )
getId方法需要注解@JsonProperty("Id"),否则getId也会加上小写的id。
我知道这是一个旧的 post,但有一个更简单的解决方案: 仅在字段上使用注释:
@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 后的第一个字母被编码为小写)。
我的解决方案是将注释移动到 setter 或 getter(两者都可以)