[英]How can I specify certain field to be serialized into JSON using Jackson?
[英]How do I ignore a class that's within a list from being serialized using Jackson?
我目前正在使用Jackson在我的程序中序列化一個大的 class ,但我似乎找不到如何忽略/跳過特定類的序列化。 我已經嘗試過使用注釋 @JsonIgnoreType ,就像這里推薦的那樣,但這似乎只適用於實際字段(而不是列表中的條目)。 我還嘗試使用@JsonIgnoreType 標記我想忽略的類並使用自定義注釋內省,但它只是保存沒有字段的空類(className 除外):
saveMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return super.hasIgnoreMarker(m) || m.getDeclaringClass().getAnnotation(JsonIgnoreType.class) != null;
}
});
...
@JsonIgnoreType
private static class ScriptA extends Script {
private int dontKeep;
public ScriptA() {
dontKeep = 25;
}
}
結果:
{
"scripts" : [ {
"className" : "com.JsonExemple$ScriptA"
}, {
"className" : "com.JsonExemple$ScriptB",
"keep" : 50
} ]
}
這是片段:
package com;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author clem585
* @created 28/02/2021 - 1:43 AM
*/
public class JsonExemple {
public static void main(String[] args) {
try {
// create Jackson JSON writer
ObjectMapper saveMapper = new ObjectMapper()
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
ObjectWriter saveWriter = saveMapper.writer().withDefaultPrettyPrinter();
// instantiate class I want to save
ExempleClass exempleClass = new ExempleClass();
// create empty file
File file = new File("D:/Desktop/exemple.json");
new File("D:/Desktop/").mkdirs();
file.createNewFile();
saveWriter.writeValue(file, exempleClass);
System.out.println("Saved exemple.json on the desktop of the D drive");
} catch (Exception e) {
System.out.println("Exception attempting to save exemple");
e.printStackTrace();
}
}
private static class ScriptB extends Script {
@JsonProperty
private int keep;
public ScriptB() {
keep = 50;
}
}
// ignore this class
private static class ScriptA extends Script {
private int dontKeep;
public ScriptA() {
dontKeep = 25;
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "className")
private static abstract class Script {
}
private static class ExempleClass {
@JsonProperty
private List<Script> scripts;
public ExempleClass() {
scripts = new ArrayList<>();
scripts.add(new ScriptA());
scripts.add(new ScriptB());
}
}
}
Jackson 在按某種類型過濾列表時似乎有點固執。 如果您在 ExempleClass 中有該類型的屬性,則@JsonIgnoreType
中的 @JsonIgnoreType 將起作用,但當它是列表中可能的子類型時則不起作用。
所以你需要一個解決方法。 一種是為 ExempleClass 定制序列化程序,或者在將腳本序列化為 JSON 之前過濾腳本:
private static class ExempleClass {
private List<Script> scripts;
public ExempleClass() {
scripts = new ArrayList<>();
scripts.add(new ScriptA());
scripts.add(new ScriptB());
}
@JsonProperty("scripts")
private List<Script> filterScriptsForJson() {
return scripts.stream()
.filter(s -> !(s instanceof ScriptA))
.collect(Collectors.toList());
}
}
如您所見,此代碼不直接注釋屬性,而是使用私有“getter”。 Jackson 將使用該方法序列化名為“scripts”的屬性(您可以在此處使用任何名稱,但我們想模仿實際的“scripts”屬性),以便該方法可以過濾列表以刪除所有 ScriptA 實例。 它也被標記為private
,因為我們不希望任何其他類使用該方法,它只存在於 Jackson 中。
如果您在代碼的其他位置使用 class ScriptA,那么您仍應盡可能嘗試使用@JsonIgnoreType
和@JsonIgnore
注釋,並且僅在這些注釋失敗時使用上述解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.