Java 使用 Jackson 复制 JSON 字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18237222/
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
Duplicate JSON Field with Hymanson
提问by
I am using Hymanson for JSON (de)serialization in conjunction with Spring. However I am having an issue with a field being twice in some cases.
我正在使用 Hymanson 与 Spring 结合进行 JSON(反)序列化。但是,在某些情况下,我遇到了一个字段是两次的问题。
I have an abstract class:
我有一个抽象类:
@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);
}
}
}
And a concrete class extend the abstract:
一个具体的类扩展了抽象:
public class EpubBookmarkJsonModel extends AbstractBookmarkJsonModel {
private static final long serialVersionUID = 1L;
// Removed other fields for brevity
public EpubBookmarkJsonModel() {
this.mimeType = "application/epub+zip";
}
}
The problem is that when I serialize this JSON, I get a duplicate mimeType
field:
问题是当我序列化这个 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"
}
I have tried using the recommendation of previousanswersto use the @JsonAutoDetect
annotation to specify that only fields on a class should be used as well as setting the same on the ObjectMapper
, however this does not fix the problem.
我曾尝试使用先前答案的建议来使用@JsonAutoDetect
注释来指定只应使用类上的字段以及在 上设置相同的字段ObjectMapper
,但这并不能解决问题。
Annotation:
注解:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
setterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
ObjectMapper:
对象映射器:
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE);
回答by Katona
This behaviour is caused by the annotations placed on class AbstractBookmarkJsonModel
:
此行为是由放置在 class 上的注释引起的AbstractBookmarkJsonModel
:
@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")
})
@JsonTypeInfo
tells Hymanson to serialize the logical type name (JsonTypeInfo.Id.NAME
) as a property (JsonTypeInfo.As.PROPERTY
) with name mimeType
(property = "mimeType"
). With @JsonSubTypes.Type
you assign the logical name application/epub+zip
to EpubBookmarkJsonModel
.
@JsonTypeInfo
告诉Hyman逊序列化的逻辑类型名称(JsonTypeInfo.Id.NAME
)作为属性(JsonTypeInfo.As.PROPERTY
)与名称mimeType
(property = "mimeType"
)。随着@JsonSubTypes.Type
分配的逻辑名称application/epub+zip
来EpubBookmarkJsonModel
。
When it comes to serialization, Hymanson serializes the logical name as a property mimeType = "application/epub+zip"
then the properties of the object among them
mimeType
which happens to have the same value as the logical name application/epub+zip
(assigned in the constructor).
在序列化方面,Hymanson 将逻辑名称序列化为一个属性,mimeType = "application/epub+zip"
然后将mimeType
其中的对象的属性
序列化为与逻辑名称application/epub+zip
(在构造函数中分配)相同的值。
I think mimeType
should be changed to objectType
in the @JsonTypeInfo
annotation or even better to remove the mimeType
field since Hymanson will take care of that through type info serialization.
我认为mimeType
应该objectType
在@JsonTypeInfo
注释中更改为,甚至更好地删除该mimeType
字段,因为 Hymanson 将通过类型信息序列化来处理该问题。
回答by ZacharyP
I was having this exact same problem with the duplicate output. I found a solution that did not involve another property, and allowed me to not remove the original property. First, I set the visible flag to true for JsonTypeInfo. Then, I added a JsonIgnore annotation to the property declaration and the getter (but not the setter). This is so far outputting the JSON correctly with only one key for the type property.
我在重复输出时遇到了完全相同的问题。我找到了一个不涉及其他属性的解决方案,并且允许我不删除原始属性。首先,我将 JsonTypeInfo 的可见标志设置为 true。然后,我在属性声明和 getter(但不是 setter)中添加了 JsonIgnore 注释。到目前为止,只有一个用于 type 属性的键才能正确输出 JSON。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, 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 {
@JsonIgnore
@JsonProperty("mimeType")
protected String mimeType;
@JsonIgnore
@JsonProperty("mimeType")
public String getMimeType() {
return mimeType;
}
@JsonProperty("mimeType")
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
}
To note, this is with fasterxml Hymanson Hymanson-databind 2.1.1
请注意,这是使用 fastxml Hymanson Hymanson-databind 2.1.1
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-databind</artifactId>
<version>2.1.1</version>
</dependency>