Jackson Introductory Part 7-JSON serialization and deserialization under the class inheritance relationship JsonTypeInfo

Jackson is the default JSON data processing framework of Spring Boot (SpringBoot), but it does not depend on any Spring library. Some friends think that Jackson can only be used in the Spring framework, but it is not. There is no such restriction. It provides many JSON data processing methods and annotations , as well as functions such as streaming API, tree model, data binding , and complex data type conversion. Although it is simple and easy to use, it is definitely not a small toy. For more content, I will write a series of 5-10 articles. Please continue to pay attention to me.

This article is the seventh in a series of articles. It is mainly to introduce to you how to implement the JSON serialization and deserialization of the parent class and the subclass in the case of Java class inheritance.

One, the construction of inheritance relationship objects

First construct a ClsShape class to represent the shape.

public class ClsShape {
}

Construct a ClsCircle class to represent a circle. And added a series of lombok annotations, Data means that it provides methods such as get, set, toString, hashCode; EqualsAndHashCode annotations are used in the inherited word classes; AllArgsConstructor and NoArgsConstructor provide full-parameter and no-parameter construction methods, respectively.

@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class ClsCircle extends ClsShape {
  Integer radius;    //弧度
}

Construct a rectangular class ClsRectangle with member variables width and height.

@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class ClsRectangle extends ClsShape {
  private Integer width;
  private Integer height;
}

Construct a ClsView class to represent the screen. There are many ClsShape shapes in the screen, so use a List package.

@Data
public class ClsView {
  private List<ClsShape> shapes;
}

Two, serialization and deserialization test

After the basic shape class and screen class are written, the following code is used to complete: the serialization process of the object to the Json string, and the process code of the Json string deserialization to the Java object.

@Test
void testJSON2Object() throws IOException {
  ClsRectangle rectangle = new ClsRectangle(7,9); //构建正方形对象
  ClsCircle circle = new ClsCircle(8); //构建长方形对象
  List<ClsShape> shapes = new ArrayList<>();  //List<多种形状>
  shapes.add(circle);
  shapes.add(rectangle);
  ClsView view = new ClsView();  //将List放入画面View
  view.setShapes(shapes);

  ObjectMapper mapper = new ObjectMapper();
  System.out.println("-- 序列化 --");
  String jsonStr = mapper.writeValueAsString(view);
  System.out.println(jsonStr);

  System.out.println("-- 反序列化 --");
  ClsView deserializeView = mapper.readValue(jsonStr, ClsView.class);
  System.out.println(deserializeView);

}

You can see that the final output on the console is as follows: The serialization process is normal, but an error was reported during deserialization.

-- 序列化 --
{"shapes":[{"radius":8},{"width":7,"height":9}]}

-- 反序列化 --
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "radius" (class com.example.demo.javabase.ClsShape), not marked as ignorable (0 known properties: ])
 at [Source: (String)"{"shapes":[{"radius":8},{"width":7,"height":9}]}"; line: 1, column: 23] (through reference chain: com.example.demo.javabase.ClsView["shapes"]->java.util.ArrayList[0]->com.example.demo.javabase.ClsShape["radius"])

The main reason for throwing an exception is that when we used to receive the result of deserialization List<ClsShape>, the Java program did not know clearly whether the shape of the ClsShape was a circular ClsCircle or a square ClsRectangle . Therefore, the string cannot be correctly deserialized into a java object.

Three, the @JsonTypeInfoannotation is added to the parent class definition

In order to solve the above problem of the deserialization of the inheritance relationship object, jackson provides us with the JsonTypeInfo annotation, which can be added to the parent class definition.

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public class ClsShape {
}

After adding @JsonTypeInfoannotations to the parent class definition , the output results of serialization and deserialization are as follows.

-- 序列化 --
{"shapes":[
{"@class":"com.example.demo.javabase.ClsCircle","radius":8},
{"@class":"com.example.demo.javabase.ClsRectangle","width":7,"height":9}
]}
-- 反序列化 --
ClsView(shapes=[ClsCircle(radius=8), ClsRectangle(width=7, height=9)])

It is worth noting that in the serialized java string, each Json object contains a new attribute @class, which is also the class that the object can be deserialized into the correct java object (@class value) under the inheritance relationship The key to the object).

Fourth, the @JsonTypeInfoannotation is added to the member variable containing the parent class

@JsonTypeInfoAnnotations can be added not only to the definition of the parent class, but also to the member variables that contain the parent class. The results of serialization and deserialization are the same as those in the third section.

@Data
public class ClsView {
  @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
  private List<ClsShape> shapes;
}

Welcome to follow my blog, there are many boutique collections

  • This article is reproduced indicate the source (en must not turn only the text): letters Gebo off .

If you think it is helpful to you, please like and share it for me! Your support is my inexhaustible creative motivation! . In addition, the author has output the following high-quality content recently, and I look forward to your attention.

Guess you like

Origin blog.csdn.net/hanxiaotongtong/article/details/108841591