0

I am new to deserialization and I am trying to deserialize the complex JSON for my class. I am using Jackson 2.12.1. I wanted to know how to map the following JSON structure to my class when there are multiple cases that map to the different root element

I have a JSON file in my Resources folder of the classpath and its something like this:

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

I have 2 class for Employee and Car separately which extends the Person abstract class and its something like this:

@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
     }
} 

This works for Employee but how can I configure it to work for all the type based on the different ROOT ELEMENT values within the JSON? I feel I am missing some basic thing can someone please help me?

PS: I am using the @Getter and @Setter from the Project Lombok

BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98

1 Answers1

0

I tried to look at many examples and the documentation of Jackson. I was finally able to get it working. This is just an example that can be used as a basis for mapping the class. In my case I was trying to see what type of element was present based on which I was mapping to different classes. So this may not work exactly as you expect but still be good for reference.

I am posting the same here so it can be helpful to someone in the future:

If following is the JSON file content:

[
  {
    "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;
      }
    }
}
BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98