我正在使用Jackson与Spring一起进行JSON(反)序列化。但是,在某些情况下,我遇到了一个字段是两次的问题。
我有一个抽象类:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "mimeType")
@JsonSubTypes({
@JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"),
@JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip")
})
public abstract class AbstractBookmarkJsonModel extends AbstractJsonModel {
protected String mimeType;
// Removed other fields for brevity
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
@Override
public String toString() {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(this);
} catch (IOException e) {
throw new IllegalStateException("Cannot convert object of type " + this.getClass().toString() + " to JSON", e);
}
}
}
而一个具体的类扩展了抽象:
public class EpubBookmarkJsonModel extends AbstractBookmarkJsonModel {
private static final long serialVersionUID = 1L;
// Removed other fields for brevity
public EpubBookmarkJsonModel() {
this.mimeType = "application/epub+zip";
}
}
问题是当我序列化这个JSON时,我得到了一个重复的mimeType
字段:
{
"mimeType": "application/epub+zip",
"mimeType": "application/epub+zip",
"userId": 24,
"acid": "ACID-000000000029087",
"added": "2013-08-14T12:02:17Z",
"epubBookmarkId": 34,
"cfi": "epubcfi(/6/4!/2/68)",
"context": "CONTEXT"
}
我已经尝试使用previousanswers的建议,使用@JsonAutoDetect
注解来指定只应使用类上的字段,并在ObjectMapper
上设置相同的字段,但这并不能解决问题。
注解:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
setterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
对象Map器:
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE);
5条答案
按热度按时间qni6mghb1#
我通过在@JsonTypeInfo注解中使用
JsonTypeInfo.As.EXISTING_PROPERTY
解决了这个问题。该项目是开源的,请在此处查看:ANS.java
nfg76nw02#
我在重复输出时遇到了同样的问题。我找到了一个不涉及其他属性的解决方案,并允许我不删除原始属性。首先,我将JsonTypeInfo的visible标志设置为true。然后,我在属性声明和getter(但不是setter)中添加了JsonIgnore注解。到目前为止,只有type属性的一个键正确地输出了JSON。
需要注意的是,这是使用fasterxml jackson jackson-databind 2.1.1实现的。
cbjzeqam3#
此行为是由放置在类
AbstractBookmarkJsonModel
上的注解引起的:@JsonTypeInfo
告诉Jackson将逻辑类型名称(JsonTypeInfo.Id.NAME
)序列化为名称为mimeType
(property = "mimeType"
)的属性(JsonTypeInfo.As.PROPERTY
)。通过@JsonSubTypes.Type
,您可以将逻辑名称application/epub+zip
分配给EpubBookmarkJsonModel
。当涉及到序列化时,Jackson将逻辑名称序列化为属性
mimeType = "application/epub+zip"
,然后将其中对象的属性mimeType
序列化,其中mimeType
恰好具有与逻辑名称application/epub+zip
相同的值(在构造函数中赋值)。我认为应该在
@JsonTypeInfo
注解中将mimeType
更改为objectType
,或者更好的做法是删除mimeType
字段,因为Jackson将通过类型信息序列化来处理这个问题。unhi4e5o4#
这种情况可能只发生在jacson lib的遗留版本中,只需将
@JsonProperty(value = "Your_CUSTOM_Name")
从字段移到getter即可解决。6psbrbz95#
我也遇到了同样的问题。我们使用的是Lombok,我通过@JsonProperty访问获得了这个工作:
我喜欢这个方案,因为:
是的,需要visible=true,这样属性才会被填充。在我们的例子中,它是一个带有一些行为调度的枚举,所以我们当然需要它来实现我们的目的,而且能够将它用于Json子类型的区分也是很棒的。