如果对象类型的变量序列化后,java jackson保留类型信息

时间:2018-10-09 09:29:49

标签: java serialization jackson deserialization objectmapper

ClassA

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

ClassB

public class ClassB {
   private String name;
}

ClassC

public class ClassC {
   String address;
}

主班

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” ??

如何检查rawData的类型?

2 个答案:

答案 0 :(得分:1)

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

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

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

  

注意:如果传入内容来自不受信任的来源,则使用默认键入可能会带来潜在的安全风险,建议不要这样做,或者如果启用,则使用setDefaultTyping传递自定义{{ 1}}实现,将要使用的合法类型列入白名单。

答案 1 :(得分:0)

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

import com.fasterxml.jackson.annotation.JsonTypeInfo;

public class ClassA {

   private String id;

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

然后两个if-else都打印“真”