Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson在子树外按名称忽略字段_Java_Json_Serialization_Filter_Jackson - Fatal编程技术网

Java Jackson在子树外按名称忽略字段

Java Jackson在子树外按名称忽略字段,java,json,serialization,filter,jackson,Java,Json,Serialization,Filter,Jackson,我有一个类结构,如下面的简化版本: public class A { public int a; public B b; public C c; public D d; public E e; } public class B { public int a; } public class C { public int a; public D d; } public class D { public int a; }

我有一个类结构,如下面的简化版本:

public class A {
    public int a;
    public B b;
    public C c;
    public D d;
    public E e;
}

public class B {
    public int a;
}

public class C {
    public int a;
    public D d;
}

public class D {
    public int a;
}

public class E {
    public int a;
}
序列化A时,我想删除所有类的A字段,C子树下包含的类除外。这意味着我想在C实例和d实例中保留a字段,但只保留C下的字段。我希望我说得清楚

我试图使用mixin或提供自定义序列化程序,但无法实现我想要的

请注意,实际上有太多的类,包括a字段,并且正在序列化的类是自动生成的。

Put@JsonIgnorePropertiesignoreUnknown=true注释到需要跳过该字段的类。它将如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
    public B b;
    public C c;
    public D d;
    public E e;
}

public class B {
    public int a;
}

public class C {
    public int a;
    public D d;
}

public class D {
    public int a;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class E {
}
将@JsonIgnorePropertiesignoreUnknown=true注释放入类中,您需要跳过该字段。它将如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
    public B b;
    public C c;
    public D d;
    public E e;
}

public class B {
    public int a;
}

public class C {
    public int a;
    public D d;
}

public class D {
    public int a;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class E {
}
对字段使用JsonFilter注释。您可以通过MixIn特性注册它,并在给定的类型和getter方法上启用它。见以下代码:

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.addMixIn(A.class, AMixIn.class);

        SimpleFilterProvider filterProvider = new SimpleFilterProvider()
            .addFilter("excludeA", SimpleBeanPropertyFilter.serializeAllExcept("a"));

        mapper.setFilterProvider(filterProvider);

        System.out.println(mapper.writeValueAsString(new A()));
    }
}

@JsonFilter("excludeA")
interface AMixIn {

    @JsonFilter("excludeA")
    B getB();

    @JsonFilter("excludeA")
    D getD();

    @JsonFilter("excludeA")
    E getE();
}
对于您的POJO型号,上述代码打印:

{
  "b" : { },
  "c" : {
    "a" : 3,
    "d" : {
      "a" : 4
    }
  },
  "d" : { },
  "e" : { }
}
另见:

对字段使用JsonFilter注释。您可以通过MixIn特性注册它,并在给定的类型和getter方法上启用它。见以下代码:

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.addMixIn(A.class, AMixIn.class);

        SimpleFilterProvider filterProvider = new SimpleFilterProvider()
            .addFilter("excludeA", SimpleBeanPropertyFilter.serializeAllExcept("a"));

        mapper.setFilterProvider(filterProvider);

        System.out.println(mapper.writeValueAsString(new A()));
    }
}

@JsonFilter("excludeA")
interface AMixIn {

    @JsonFilter("excludeA")
    B getB();

    @JsonFilter("excludeA")
    D getD();

    @JsonFilter("excludeA")
    E getE();
}
对于您的POJO型号,上述代码打印:

{
  "b" : { },
  "c" : {
    "a" : 3,
    "d" : {
      "a" : 4
    }
  },
  "d" : { },
  "e" : { }
}
另见:


多亏了@MichałZiober提供的提示,我能够解决以下问题:

// custom serializer for C class, which in fact serializes all fields
public class CNormalSerializer extends JsonSerializer<C> {
    @Override
    public void serialize(C value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeRawValue(new ObjectMapper().writeValueAsString(value));
    }
}

@JsonFilter(JsonFieldFilter.JSON_FILTER)
public class JsonFieldFilter {
    public static final String JSON_FILTER = "Json filter";
}

public class X {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        // registered standard C serializer
        SimpleModule simpleModule = new SimpleModule();
        CNormalSerializer cSerializer = new CNormalSerializer ();
        simpleModule.addSerializer(C.class, cSerializer);
        objectMapper.registerModule(simpleModule);
        // added the 'a' filter
        objectMapper.addMixIn(Object.class, JsonFieldFilter.class);
        String[] ignorableFieldNames = {"a"};
        FilterProvider filters = new SimpleFilterProvider().addFilter(JsonFieldFilter.JSON_FILTER, SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
        ObjectWriter writer = objectMapper.writer(filters);

        writer.writeValueAsString(new A());
    }
}

多亏了@MichałZiober提供的提示,我能够解决以下问题:

// custom serializer for C class, which in fact serializes all fields
public class CNormalSerializer extends JsonSerializer<C> {
    @Override
    public void serialize(C value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeRawValue(new ObjectMapper().writeValueAsString(value));
    }
}

@JsonFilter(JsonFieldFilter.JSON_FILTER)
public class JsonFieldFilter {
    public static final String JSON_FILTER = "Json filter";
}

public class X {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        // registered standard C serializer
        SimpleModule simpleModule = new SimpleModule();
        CNormalSerializer cSerializer = new CNormalSerializer ();
        simpleModule.addSerializer(C.class, cSerializer);
        objectMapper.registerModule(simpleModule);
        // added the 'a' filter
        objectMapper.addMixIn(Object.class, JsonFieldFilter.class);
        String[] ignorableFieldNames = {"a"};
        FilterProvider filters = new SimpleFilterProvider().addFilter(JsonFieldFilter.JSON_FILTER, SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
        ObjectWriter writer = objectMapper.writer(filters);

        writer.writeValueAsString(new A());
    }
}

谢谢你的帮助。实际上,该模型相当复杂,无法创建相应的MixIn类。我能够解决我的答案中的问题。再次感谢!谢谢你的帮助。实际上,该模型相当复杂,无法创建相应的MixIn类。我能够解决我的答案中的问题。再次感谢!