• 公用技术——数据格式——JSON——Jackson类库——复杂对象


      本篇介绍复杂对象下遇到的一些场景。个人总结的有以下两种。

    第一种是循环引用,即A--->B---->C--->A等类似的场景。

    第二种是父子类,例如User对象中存在Phone对象,Phone对象下存在dialPhone,mobilePhone等子类

    1、循环引用

    1.1   @JsonIdentifyInfo

    它给对象添加一个ID,注解的作用是指定ID的类型。有四种值

    StringIdGenerator:生成字符串ID

    IntSequenceGenerator:使用序列生成器生成ID

    UUIDGenerator:使用UUID生成器

    PropertyGenerator:使用属性作为ID,需要设置property属性,它的值为属性名称。

    例如Role类下存在User,User类下存在Role。序列化User时,在User类上添加@JsonIdentifyInfo

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,  property = "id")
    public class User {
    }
    

      意思是使用User的id属性作为唯一标识。property的默认值为id,上述的property可以省略。

    1.2 @JsonManagedReference & @JsonBackReference

    在循环引用链上,前后是一个相对的概念,@JsonManagedReference添加在之前的节点,@JsonBackReference添加在之后的节点。这样在序列化之前节点的对象时会忽略之后节点类型的属性。

    例如在序列化User对象时,它的循环引用链为User--->Role---->User,在User上添加@JsonManagedReference,在Role上添加@JsonBackReference,此时在序列化User时,会忽略User的Role类型属性。

    public class User {
        @JsonManagedReference
        private Role role;
    }
    
    public class Role {
        @JsonBackReference
        private User user;
    }
    

    1.3   @JsonIdentityReference

    它配合@JsonIdentifyInfo使用,添加在类上时,循环引用的对象会被序列化为其ID。

    例如

    public class User {
        @JsonIdentityReference(alwaysAsId = true)
        private Role role;
    }
    
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    public class Role {
    
       private String id;
    
        @JsonBackReference
        private User user;
    }
    

      当属性上添加@JsonIdentifyReference时,属性类型上必须有@JsonIndentifyInfo注解,且ID生成器类型必须为PropertyGenerator。

    2、父类子类

    使用示例说明,假设存在Shape父类,它的子类有Rectangle,Circle,Square。在List<Shape>集合中存在Rectangle,Circle,Square三种类型的元素,默认情况下打印时会添加类型的信息。

    {
      "shapes": [
        {
          "className": "com.example.Rectangle",
          "w": 3,
          "h": 6
        },
        {
          "className": "com.example.Circle",
          "radius": 5
        }
      ]
    }
    

    2.1     @JsonTypeInfo

    在shapes属性上添加@JsonTypeInfo,可以控制类型的信息。它有三个属性。

    • use属性,它控制类型信息的值。它有三个值,
    1. Id.CLASS:类的全名,默认值
    2. Id.MINIMAL_CLASS:类的缩写名称
    3. Id.NAME: 自定义类的名称。此时需要在子类上添加@JsonTypeName。
    • as属性,它控制生成的结构。它有五个值
    1. PROPERTY:指定属性名称,该属性的值为类信息。
    2. EXISTING_PROPERTY: 使用已存在的属性
    3. EXTERNAL_PROPERTY:TODO
    4. WRAPPER_OBJECT:生成JSON串的格式为 classInfo:{// 属性},例如 {"com.logicbig.Rectangle":{"w":3,"h":6}, // 后续部分}
    5. WRAPPER_ARRAY:类信息作为单独的一项,生成的JSON串格式为[classInfo,{// 属性},例如 [["com.logicbig.example.Rectangle",{"w":3,"h":6}]

    2.2     @JsonTypeId

      在属性上添加@JsonTypeId注解,该属性的值为类型的信息,通常和@JsonTypeName一起使用。

    @JsonTypeName("rectangle")
    public class Rectangle extends Shape {
      @JsonTypeId
      private String classType;
    }
    

      Json串为{"classType":"rectangle","w":3,"h":6}。

    2.3     @JsonSubTypes

      添加在父类上,指定包含的子类列表

    // 父类
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
    @JsonSubTypes({
          @JsonSubTypes.Type(value = Rectangle.class),
          @JsonSubTypes.Type(value = Circle.class),
          @JsonSubTypes.Type(value = Square.class)})
    public abstract class Shape {
    }
    
    // 子类
    @JsonTypeName("rectangle")
    public class Rectangle extends Shape {
    ...
    }
  • 相关阅读:
    高校招生说明网页被挂马 考生浏览需谨慎 狼人:
    匹配情况hdu4451Dressing
    方法springBean Lifecycle in Spring
    android颜色关于Android TabHost切换Tab字体的颜色背景颜色改变
    推荐美国简单的选项卡功能实现
    按钮function关闭子页面刷新父页面中部分控件数据
    编码文件AndroidStudio初体验:解决Execution failed for task ':TestAndroid:compileDebug'.
    图片类关于实现图片剪切功能的相关类的学习心得
    nullnull10879 Code Refactoring
    java独立HDU 2845 Beans
  • 原文地址:https://www.cnblogs.com/rain144576/p/14565060.html
Copyright © 2020-2023  润新知