Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.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_Jackson_Jackson Databind - Fatal编程技术网

Java Jackson用于嵌套字段序列化的多个不同架构

Java Jackson用于嵌套字段序列化的多个不同架构,java,json,jackson,jackson-databind,Java,Json,Jackson,Jackson Databind,我想在使用Jackson序列化时使用几种不同的模式。 假设我有以下几个类: public class Department { private Person head; private Person deputy; private List<Person> staff; // getters and setters } public class Person { private String name pr

我想在使用Jackson序列化时使用几种不同的模式。 假设我有以下几个类:

public class Department {
      private Person head;
      private Person deputy;
      private List<Person> staff;
      // getters and setters
}

public class Person {
       private String name
       private int code;
      // getters and setters
}
,并使用第二个模式:

{
    "head" : {
        "name" : "John",
        "code" : 123
     },
     "deputy" : { 
        "name" : "Jack",
        "code" : "234"
     },
     "staff": [
        { 
            "name" : "Tom",
            "code" : "345"
         },
         { 
            "name" : "Matt",
            "code" : "456"
         },
     ]
}
问题:我应该如何与杰克逊合作

注意:这些类只是示例。对于这个简单的示例,可以编写四个不同的包装器类,但请考虑一个包含十几个类的复杂示例,每个类都有几个字段。使用包装类,我们应该生成大量的样板代码


任何帮助都将不胜感激

Jackson库中有一个功能JsonViews

您需要为视图创建一个类

public class Views {

    public static class Normal{}

    public static class Extended extends Normal{}

}
接下来为Department类添加注释

import com.fasterxml.jackson.annotation.JsonView;

import java.util.List;

public class Department {

    @JsonView(Views.Normal.class)
    private Person head;

    @JsonView(Views.Normal.class)
    private Person deputy;

    @JsonView(Views.Extended.class)
    private List<Person> staff;

    public Person getHead() {
        return head;
    }

    public void setHead(Person head) {
        this.head = head;
    }

    public Person getDeputy() {
        return deputy;
    }

    public void setDeputy(Person deputy) {
        this.deputy = deputy;
    }

    public List<Person> getStaff() {
        return staff;
    }

    public void setStaff(List<Person> staff) {
        this.staff = staff;
    }
}
在序列化对象的main函数中,需要启用相应的视图

public class Main {


    static Department createDepartment(){
        Department department = new Department();
        Person head = new Person("John", 123);
        Person deputy = new Person("Jack", 234);
        List<Person> personList = Arrays.asList(new Person("Tom", 345), new Person("Matt", 456));
        department.setHead(head);
        department.setDeputy(deputy);
        department.setStaff(personList);
        return department;

    }

    public static void main(String[] args) throws JsonProcessingException {

        Department department = createDepartment();

        ObjectMapper mapper = new ObjectMapper();

        String normal = mapper.writerWithView(Views.Normal.class).writeValueAsString(department);
        String extended = mapper.writerWithView(Views.Extended.class).writeValueAsString(department);

        System.out.println("Normal View - " + normal);
        System.out.println("Extended View - " + extended);
   }
}

尽管@bigbounty解决方案非常优秀,而且我认为除了特定的
DTO
s之外,
View
s通常也是一种方式,但在这种情况下,它可能不适用,因为对于同一类
Person
来说,我们实际上需要在同一个视图中有两种不同的行为

可以用来解决这个问题

main
方法计算所需的图形:


公共静态void main(字符串[]args)引发JsonProcessingException{
final PropertyFilter departmentFilter=新的SimpleBeanPropertyFilter(){
@凌驾
公共空字段
(对象pojo、JsonGenerator jgen、SerializerProvider提供程序、PropertyWriter编写器)
抛出异常{
如果(包括(作者)){
最终字符串名=writer.getName();
如果(!name.equals(“代理”)和(&!name.equals(“职员”)){
writer.serializeAsField(pojo、jgen、provider);
返回;
}
如果(姓名等于(“员工”)){
返回;
}
//理想情况下,它不应该被静音。
最终部门=(部门)pojo;
最终人员代理=department.getsubsive();
代理主席:设定码(-1);
作者:Asfield(部门、jgen、供应商);
}如果(!jgen.canOmitFields()){//从2.3开始
writer.MittedField(pojo、jgen、提供者);
}
}
@凌驾
受保护的布尔值包括(BeanPropertyWriter){
返回true;
}
@凌驾
受保护的布尔值包括(PropertyWriter写入程序){
返回true;
}
};
final PropertyFilter personFilter=新的SimpleBeanPropertyFilter(){
@凌驾
公共空字段
(对象pojo、JsonGenerator jgen、SerializerProvider提供程序、PropertyWriter编写器)
抛出异常{
如果(包括(作者)){
如果(!writer.getName().equals(“code”)){
writer.serializeAsField(pojo、jgen、provider);
返回;
}
int code=((Person)pojo.getCode();
如果(代码>=0){
writer.serializeAsField(pojo、jgen、provider);
}
}如果(!jgen.canOmitFields()){//从2.3开始
writer.MittedField(pojo、jgen、提供者);
}
}
@凌驾
受保护的布尔值包括(BeanPropertyWriter){
返回true;
}
@凌驾
受保护的布尔值包括(PropertyWriter写入程序){
返回true;
}
};
最终部门=新部门();
最终负责人=新人(“约翰”,123);
最终代理人=新人(“杰克”,234);
最终列表personList=Arrays.asList(新人(“汤姆”,345),新人(“马特”,456));
部门。设置头(head);
副部长(副部长);
部门设置人员(人员列表);
最终ObjectMapper映射器=新ObjectMapper();
final FilterProvider Schema1 Filters=新的SimpleFilterProvider()
.addFilter(“deparmentFilter”,departmentFilter)
.addFilter(“personFilter”,personFilter)
;
setFilterProvider(Schema1过滤器);
最后一个字符串,带有chema1filters=mapper.writeValueAsString(department);
System.out.printf(“模式1:\n%s\n”,带有模式1筛选器);
//一旦类被@JsonFilter注释,您就必须维护过滤器
//我们可以使用两个无操作内置过滤器
final FilterProvider schema2Filters=新的SimpleFilterProvider()
.addFilter(“deparmentFilter”,SimpleBeanPropertyFilter.serializeAll())
.addFilter(“personFilter”,SimpleBeanPropertyFilter.serializeAll())
;
setFilterProvider(schema2Filters);
带有chema2filters=mapper.writeValueAsString(部门)的最终字符串;
System.out.printf(“模式2:\n%s\n”,带有模式2过滤器);
}
要使此代码正常工作,必须使用以下内容注释
部门
类:

@JsonFilter(“deparmentFilter”)
以及
人员
类:

@JsonFilter(“personFilter”)
如您所见,Jackson还提供了几个内置过滤器

此代码与您提出的测试类非常耦合,但可以通过使其更通用的方式对其进行扩展


请看一看如何创建您自己的过滤器的示例。

谢谢您的详细回答。我熟悉JsonViews。但我认为这不能解决我的问题。例如,您的输出与我预期的json不同。因为映射程序总是在两个模式中完全相同地序列化
subsive
。但我想在每个模式中对其进行不同的序列化。您需要创建不同的视图。我是说,瓦希德雷扎伊的班级没有抓住你。你能再解释一下吗?你的意思是我必须为
Person
类创建不同的视图吗?如果是肯定的,我应该如何在
部门
类中注释
副手
?@bigbounty的答案是正确的@vahidreza@JsonView可以接受一个视图数组。您可以注释public class Person { private String name; private int code; public Person(String name, int code) { this.name = name; this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
public class Main {


    static Department createDepartment(){
        Department department = new Department();
        Person head = new Person("John", 123);
        Person deputy = new Person("Jack", 234);
        List<Person> personList = Arrays.asList(new Person("Tom", 345), new Person("Matt", 456));
        department.setHead(head);
        department.setDeputy(deputy);
        department.setStaff(personList);
        return department;

    }

    public static void main(String[] args) throws JsonProcessingException {

        Department department = createDepartment();

        ObjectMapper mapper = new ObjectMapper();

        String normal = mapper.writerWithView(Views.Normal.class).writeValueAsString(department);
        String extended = mapper.writerWithView(Views.Extended.class).writeValueAsString(department);

        System.out.println("Normal View - " + normal);
        System.out.println("Extended View - " + extended);
   }
}
Normal View - {"head":{"name":"John","code":123},"deputy":{"name":"Jack","code":234}}
Extended View - {"head":{"name":"John","code":123},"deputy":{"name":"Jack","code":234},"staff":[{"name":"Tom","code":345},{"name":"Matt","code":456}]}