Jackson learning four: WRAP_ROOT_VALUE (root object)

Welcome to my GitHub

https://github.com/zq2599/blog_demos
content: classification summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

Series articles summary

Overview of this article

This article is the fourth article in the "Jackson Learning" series. I learned about common APIs and can perform the most basic serialization and deserialization operations. The next thing to learn is Jackson's powerful annotation capabilities. This article is about root Object characteristics, the main contents are as follows:

  1. About the root object
  2. POJO class for testing
  3. Serialization
  4. Deserialization combat

About the root object (WRAP_ROOT_VALUE)

  1. For a POJO instance with only two fields, id and name , the normal serialization results are as follows:
{
    
    
  "id" : 1,
  "name" : "book"
}
  1. When jackson serializes, he can wrap another layer outside the above json. The official name is WRAP_ROOT_VALUE . This article is called the root object . As shown below, the entire json has only one key-value pair, the key is aaabbbccc , and the inside value is the POJO instance. The values ​​of the id and name fields:
{
    
    
  "aaabbbccc" : {
    
    
    "id" : 2,
    "name" : "food"
  }
}

Summary in advance

A summary of the root object characteristics in advance, so if you have limited time, just read this section:

  • First look at the serialization scenario:
  1. Execute the following code, jackson will increase the root object during serialization:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. The key of the root object is the class name of the instance by default. If the instance has the JsonRootName annotation, it is the value of the annotation;
  2. The value of the root object is as follows, which is equivalent to the serialization result when the root object is not supported :
{
    
    
  "id" : 1,
  "name" : "book"
}
  • Look at the deserialization scenario:
  1. Execute the following code, jackson will first parse the root object when deserializing:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. The key of the root object is the class name of the instance by default. If the instance has the JsonRootName annotation, it is the value of the annotation;
  2. The value of the root object is as follows, which is equivalent to the json string used for deserialization when the root object is not supported :
{
    
    
  "id" : 1,
  "name" : "book"
}

Prepare two POJO classes

By comparison, we can understand the role of JsonRootName more clearly. For the next study, we will prepare two POJO classes, one without JsonRootName annotation, and the other with JsonRootName annotation:

  1. The one named Order1.java has no JsonRootName annotation:
public class Order1 {
    
    
    private int id;
    private String name;
	// 省去get、set、toString方法
	...
}
  1. The one named Order2.java has JsonRootName annotation and the value is aaabbbccc :
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName(value = "aaabbbccc")
public class Order2 {
    
    
	private int id;
    private String name;
	// 省去get、set、toString方法
	...
}
  • It can be seen that the codes of Order1 and Order2 are the same, the only difference is that Order2 has the annotation JsonRootName;

Serialization

  1. You need to set the WRAP_ROOT_VALUE property, jackson will support the root object, and the JsonRootName annotation will work. The setting code is as follows:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. Write a piece of code to perform serialization when the WRAP_ROOT_VALUE property is not turned on, and then turn on the WRAP_ROOT_VALUE property to perform serialization. Try to compare:
public static void main(String[] args) throws Exception {
    
    
        // 实例化Order1和Order2
        Order1 order1 = new Order1();
        order1. setId(1);
        order1.setName("book");

        Order2 order2 = new Order2();
        order2. setId(2);
        order2.setName("food");

        // 没有开启WRAP_ROOT_VALUE的时候
        logger.info("没有开启WRAP_ROOT_VALUE\n");
        ObjectMapper mapper1 = new ObjectMapper();
        // 美化输出
        mapper1.enable(SerializationFeature.INDENT_OUTPUT);

        logger.info("没有JsonRootName注解类,序列化结果:\n\n{}\n\n", mapper1.writeValueAsString(order1));
        logger.info("有JsonRootName注解的类,序列化结果:\n\n{}\n\n\n\n", mapper1.writeValueAsString(order2));

        // 开启了WRAP_ROOT_VALUE的时候
        logger.info("开启了WRAP_ROOT_VALUE\n");
        ObjectMapper mapper2 = new ObjectMapper();
        // 美化输出
        mapper2.enable(SerializationFeature.INDENT_OUTPUT);
        // 序列化的时候支持JsonRootName注解
        mapper2.enable(SerializationFeature.WRAP_ROOT_VALUE);

        logger.info("没有JsonRootName注解类,序列化结果:\n\n{}\n\n", mapper2.writeValueAsString(order1));
        logger.info("有JsonRootName注解的类,序列化结果:\n\n{}", mapper2.writeValueAsString(order2));
    }
  1. The execution result is as follows, the role of JsonRootName in serialization is clear: the key of the root object is specified:
    Insert picture description here

Deserialization (default setting)

  1. Without any settings, the following string is used to deserialize into an Order2 object, will it succeed?
{
    
    
  "id" : 2,
  "name" : "food"
}
  1. It is possible to try:
    Insert picture description here
  2. Can the following string be deserialized into an Order2 object?
{
    
    
  "aaabbbccc" : {
    
    
    "id" : 2,
    "name" : "food"
  }
}
  1. The code and results are shown in the following figure. Jackson does not recognize the key aaabbbccc during deserialization , because Jackson does not support the root object at this time:
    Insert picture description here
  • Summary: By default, the json string cannot have a root object during deserialization;

Deserialization (open UNWRAP_ROOT_VALUE attribute)

  1. If the UNWRAP_ROOT_VALUE attribute is enabled, the json string used for deserialization must have a root object. The code to enable the UNWRAP_ROOT_VALUE attribute is as follows:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. The code and results are shown in the following figure. It can be seen that the json string with the root object can be deserialized successfully. The key of the root object is the value attribute of the JsonRootName annotation:
    Insert picture description here
  2. It is worth noting that in the above json string, the key of the root object is aaabbbccc , which is consistent with the value of the JsonRootName annotation of Order2 . If it is inconsistent, the deserialization will fail , as shown in the following figure:
    Insert picture description here
  • At this point, Jackson’s WRAP_ROOT_VALUE feature has been studied. This is a very common function in web development. It is used to wrap the outermost layer in order to add additional content as a whole. I hope to bring you reference;

Welcome to follow my public account: programmer Xin Chen

Insert picture description here

Guess you like

Origin blog.csdn.net/boling_cavalry/article/details/108298858