使用 Java Jackson 反序列化 json 并基于根元素调用与该根元素中的 Json 对象匹配的不同 类

Deserialize json using Java Jackson and based on the root element call different classes that match the Json Object within that root element

我是反序列化的新手,我正在尝试为我的 class 反序列化复杂的 JSON。我正在使用 Jackson 2.12.1。我想知道当有多个案例映射到不同的根元素时如何将以下 JSON 结构映射到我的 class

我的 class 路径的 Resources 文件夹中有一个 JSON 文件,它是这样的:

   {
      "Employee":{
         "firstName":"First Name",
         "lastName":"Last Name",
         "department":"Department"
      },
      "Student":{
         "firstName":"Student First Name",
         "lastName":"Student Last Name",            
         "studentID":"1234"
      }
   }

我有 2 个 class 用于 EmployeeCar 分别扩展了 Person 摘要 class 和它像这样的东西:

@Getter
@Setter
public abstract class person{
    private String firstName;
    private String lastName;
}

@Getter
@Setter
@JsonRootName(value = "Employee")
public Employee extends person{
    private String department;
}

@Getter
@Setter
@JsonRootName(value = "Student")
public Student extends person{
    private String studentID;
}

public class MainClass{

     public static void main(String []args){
        String jsonFile = FileUtils.readFileToString(new File("src/main/resources/myFile.json"), "UTF-8");
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
        Employee eventInfo = objectMapper.readValue(jsonFile, Employee.class);

        //This works for Employee but I want to make sure that it works for Student as well based on the ROOT ELEMENT value within the JSON
     }
} 

这适用于 Employee,但我如何根据 JSON 中不同的 ROOT ELEMENT 值将其配置为适用于所有类型?我觉得我缺少一些基本的东西,有人可以帮助我吗?

PS:我正在使用来自 Project Lombok

的 @Getter 和 @Setter

我试图查看 Jackson 的许多示例和文档。我终于能够让它工作了。这只是一个示例,可以作为映射 class 的基础。在我的例子中,我试图根据映射到不同 classes 的元素类型来查看存在的元素类型。所以这可能无法完全按照您的预期工作,但仍然可以作为参考。

我在这里发布相同的内容,以便将来对某人有所帮助:

如果以下是JSON文件内容:

[
  {
    "isA": "Type1",
    "name": "Test",
    "foo": "val1",
    "foo": "val2",
    "bar": "val3",
    "foo": {
      "myField": "Value1",
      "myField": "value2"
    }
  },
  {
    "isA": "Type2",
    "name": "Test1",
    "foo": "val1",
    "foo": "val2",
    "bar": "val3",
    "foo": {
      "myField": "Value1",
      "myField": "value2"
    }
  }
]


public void xmlConverter(InputStream jsonStream) throws IOException {
    // Get the JSON Factory and parser Object
    final JsonParser jsonParser = new JsonFactory().createParser(jsonStream);
    final ObjectMapper objectMapper = new ObjectMapper();
    jsonParser.setCodec(objectMapper);
    
    // Check the first element is ARRAY if not then invalid JSON throw error
    if (jsonParser.nextToken() != JsonToken.START_ARRAY) {
      throw new IllegalStateException("Expected content to be an array");
    }
    
    jsonParser.nextToken();
    
    // Loop until the end of the events file
    while (jsonParser.nextToken() != JsonToken.END_ARRAY) {

      // Get the node
      final JsonNode jsonNode = jsonParser.readValueAsTree();

      //Check if the JsonNode is valid if not then exit the process
      if (jsonNode == null || jsonNode.isNull()) {
        System.out.println("End Of File");
        break;
      }

      // Get the eventType
      final String eventType = jsonNode.get("isA").asText();

      // Based on eventType call different type of class
      switch (eventType) {
        case "Type1":
          final Type1 type1Info = objectMapper.treeToValue(jsonNode, Type1.class);
          break;
        case "Type2":
          final Type2 type2Info = objectMapper.treeToValue(jsonNode, Type2.class);
          break;
        default:
          System.out.println("JSON event does not match any of event : " + eventType);
          break;
      }
    }
}