Java 我如何忽略一个';使用Jackson序列化列表中的哪些内容?
我目前正在使用序列化程序中的一个大类,但我似乎找不到如何忽略/跳过被序列化的特定类。我尝试过像推荐的那样使用注释@JsonIgnoreType,但这似乎只适用于实际字段(而不是列表中的条目)。我还尝试使用@JsonIgnoreType标记我想忽略的类,并使用自定义注释内省器,但它只保存空类而不包含字段(className除外): 结果:Java 我如何忽略一个';使用Jackson序列化列表中的哪些内容?,java,serialization,jackson,Java,Serialization,Jackson,我目前正在使用序列化程序中的一个大类,但我似乎找不到如何忽略/跳过被序列化的特定类。我尝试过像推荐的那样使用注释@JsonIgnoreType,但这似乎只适用于实际字段(而不是列表中的条目)。我还尝试使用@JsonIgnoreType标记我想忽略的类,并使用自定义注释内省器,但它只保存空类而不包含字段(className除外): 结果: { "scripts" : [ { "className" : "com.JsonEx
{
"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());
}
}
}
package-com;
导入com.fasterxml.jackson.annotation.JsonProperty;
导入com.fasterxml.jackson.annotation.JsonTypeInfo;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.ObjectWriter;
导入com.fasterxml.jackson.databind.SerializationFeature;
导入java.io.File;
导入java.util.ArrayList;
导入java.util.List;
/**
*@作者clem585
*@创建于2021年2月28日-凌晨1:43
*/
公共类JsonExemple{
公共静态void main(字符串[]args){
试一试{
//创建JSON编写器
ObjectMapper saveMapper=新的ObjectMapper()
.configure(SerializationFeature.FAIL\u在\u空\u bean上,false);
ObjectWriter saveWriter=saveMapper.writer().withDefaultPrettyPrinter();
//实例化我要保存的类
exampleClass exampleClass=新的exampleClass();
//创建空文件
File File=新文件(“D:/Desktop/example.json”);
新文件(“D:/Desktop/”).mkdirs();
createNewFile();
saveWriter.writeValue(文件,ExampleClass);
System.out.println(“D驱动器桌面上保存的example.json”);
}捕获(例外e){
System.out.println(“试图保存示例的异常”);
e、 printStackTrace();
}
}
私有静态类ScriptB扩展脚本{
@JsonProperty
私人内部控制;
公共脚本b(){
保持=50;
}
}
//忽略这个类
私有静态类ScriptA扩展脚本{
私人住宅;
公共脚本(){
dontKeep=25;
}
}
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,property=“className”)
私有静态抽象类脚本{
}
私有静态类exampleClass{
@JsonProperty
私有列表脚本;
公共示例类(){
scripts=newarraylist();
scripts.add(新ScriptA());
添加(新的ScriptB());
}
}
}
对于按特定类型筛选列表,Jackson似乎有点固执<如果您在ExampleClass中具有该类型的属性,则ScriptA中的code>@JsonIgnoreType将起作用,但如果它是列表中可能的子类型,则不起作用
所以你需要一个变通办法。一种是ExampleClass的自定义序列化程序,或者在将脚本序列化为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());
}
}
私有静态类exampleClass{
私有列表脚本;
公共示例类(){
scripts=newarraylist();
scripts.add(新ScriptA());
添加(新的ScriptB());
}
@JsonProperty(“脚本”)
私有列表过滤器scriptsforjson(){
返回scripts.stream()
.filter(s->!(脚本的s实例))
.collect(Collectors.toList());
}
}
如您所见,此代码不直接注释属性,而是使用私有的“getter”。Jackson将使用该方法序列化名为“scripts”的属性(您可以在此处使用任何名称,但我们希望模拟实际的“scripts”属性),以便该方法可以过滤列表以删除所有ScriptA实例。它也被标记为private
,因为我们不希望任何其他类使用该方法,它只存在于Jackson中
如果您在代码中的其他地方使用了ScriptA类,那么您仍然应该尽可能使用
@JsonIgnoreType
和@JsonIgnore
注释,并且仅在注释失败时使用上述解决方法。谢谢!我刚刚使用了这个,但将过滤器修改为按注释过滤,使其更容易应用于多个脚本:.filter(s->s.getClass().getAnnotation(JsonIgnoreType.class)==null)
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());
}
}