【发布时间】:2021-08-20 07:21:32
【问题描述】:
我正在使用Jackson 序列化POJO。这个POJO 类由一些字段和一个Map<String,Object> others 组成。我在为这个MAP 字段编写JSON 时使用Custom Serializer。我想避免得到Map field name "others"´ in my JSON. Hence, I am using the @JsonValueon theMapfield but using the@JsonValueis conflicting with@JsonTypeInfo`。我在课堂上需要这两个注释,我该如何实现?
截至目前,我得到的JSON 如下:(@JsonValue 和 @JsonTypeInfo)
[ "Customer", {
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
} ]
我想同时获得JSON 和@JsonValue 和@JsonTypeInfo:(如您所见others 键已提交,但其值直接添加到JSON)
{
"isA" : "Customer",
"name" : "Batman",
"google:sub" : "MyValue-1",
"age" : "2008"
}
我能够获得输出,但我需要从我的班级中删除注释:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
但如果我删除它,我将不会在我的 JSON 中获得 isA 属性。我想知道如何使Jackson Json Serializer 与@JsonTypeInfo 和@JsonValue 一起工作。
不带@JsonTypeInfo但带@JsonValue的输出:
{
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
}
输出不带@JsonValue,但带@JsonTypeInfo
{
"isA" : "Customer",
"name" : "",
"age" : "",
"others" : {
"name" : "Rise Against",
"google:sub" : "MyValue-1",
"age" : "2000"
}
}
以下是我的Customer类Pojo:
@XmlRootElement(name = "Customer")
@XmlType(name = "Customer", propOrder = {"name", "age", "others"})
@XmlAccessorType(XmlAccessType.FIELD)
@NoArgsConstructor
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@JsonIgnoreType
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, visible = true, property = "isA")
public class Customer {
@XmlElement(name = "name", required = true)
private String name;
@XmlElement(name = "age", required = true)
private String age;
@JsonSerialize(using = CustomExtensionsSerializer.class)
@XmlJavaTypeAdapter(TestAdapter.class)
@XmlPath(".")
@JsonValue
private Map<String, Object> others = new HashMap<>();
@JsonAnySetter
public void setOthers(String key, Object value) {
others.put(key, value);
}
public Map<String, Object> getOthers() {
return others;
}
}
以下是我的`自定义序列化程序:
public class CustomExtensionsSerializer extends JsonSerializer<Map<String, Object>> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
recusiveSerializer(value, gen, serializers);
gen.writeEndObject();
}
public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
for (Map.Entry<String, Object> extension : value.entrySet()) {
if (extension.getValue() instanceof Map) {
//If instance is MAP then call the recursive method
recusiveSerializer((Map) extension.getValue(), gen, serializers);
} else if (extension.getValue() instanceof String) {
//If instance is String directly add it to the JSON
gen.writeStringField(extension.getKey(), (String) extension.getValue());
} else if (extension.getValue() instanceof ArrayList) {
//If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
for (Object dupItems : (ArrayList<String>) extension.getValue()) {
if (dupItems instanceof Map) {
recusiveSerializer((Map) dupItems, gen, serializers);
} else {
gen.writeStringField(extension.getKey(), (String) extension.getValue());
}
}
gen.writeEndObject();
}
}
}
}
【问题讨论】:
标签: java json serialization jackson jackson2