java jackson 在对象类型变量序列化后保留类型信息

java jackson keep type information after serialize if variable of type Object

ClassA

public class ClassA {
   private String id;
   private Object rawData;
}

ClassB

public class ClassB {
   private String name;
}

ClassC

public class ClassC {
   String address;
}

主要Class

public class MainExample {
   public static void main( String[] args ) throws IOException {

      ObjectMapper mapper = new ObjectMapper(  );

      ClassB classB = new ClassB();
      //ClassC classC = new ClassC();
      ClassA classA = new ClassA();
      classA.setRawData(  classB );
      //classA.setRawData(  classC );

      if (classA.getRawData() instanceof ClassB) {
         System.out.println("true ");
      } else {
         System.out.println("false");
      }

      String classAString = mapper.writeValueAsString( classA );
      ClassA a = mapper.readValue( classAString, ClassA.class );

      if (a.getRawData() instanceof ClassB) {
         System.out.println("true ");
      } else {
         System.out.println("false");
      }
   }
}

为什么第一个 if-else 打印 "TRUE" 和第二个 if-else 打印 "false"??

如何检查原始数据的类型?

mapper.writeValueAsString(classA) 会将实例序列化为类似于 {"rawData":{}} 的内容。

反序列化 {} 时,默认映射器会失败,因为它将 {} 视为不可序列化的类型。如果您之前已将 SerializationFeature.FAIL_ON_EMPTY_BEANS 配置为 false,您将创建一个空的 Object

您可能希望使用 mapper.enableDefaultTyping(); 在 JSON 中包含类型信息,从而反序列化为正确的类型。

NOTE: use of Default Typing can be a potential security risk if incoming content comes from untrusted sources, and it is recommended that this is either not done, or, if enabled, use setDefaultTyping passing a custom TypeResolverBuilder implementation that white-lists legal types to use.

我们还可以使用 jackson 库中的@JsonTypeInfo 来保存 class 信息

import com.fasterxml.jackson.annotation.JsonTypeInfo;

public class ClassA {

   private String id;

   @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, property="@class")
   private Object rawData;
}

然后两个 if-else 打印 "True".