JSONPath, Object Mapper, Jackson, Rest Assured Deserialization (API response ArrayList,Simple JSON, Nested JSON) - Bug Reaper

                  Bug Reaper

Lean about Automation Testing,Selenium WebDriver,RestAssured,Appium,Jenkins,JAVA,API Automation,TestNG,Maven, Rest API, SOAP API,Linux,Maven,Security Testing,Interview Questions

Sunday 19 April 2020

JSONPath, Object Mapper, Jackson, Rest Assured Deserialization (API response ArrayList,Simple JSON, Nested JSON)


Note: JAVA Object is converted into JSON Object

Note: JAVA Array is converted into JSON Array


Every JSON object is composed on an inherent hierarchy and structure. Every JSON ends up creating a tree of nodes, where each node is a JSON Element

How to Query JSON using JSONPath?

JSONPath creates a uniform standard and syntax to define different parts of a JSON document. JSONPath defines expressions to traverse through a JSON document to reach to a subset of the JSON.


Root Node

Root node is represented by $ sign.
This returns all the nodes present in JSON Document

Get Children

We use . Dot operator

Example: $.Node[*].AnotherNode

Deserialize Json Response

Representing a JSON, or any structured data including XML, into a programming class is called Deserialization of JSON. The term Deserialization here means the conversion from  String form of JSON to a Class form


Sample API Response



   "data":
      "id":2,
      "email":"janet.weaver@reqres.in",
      "first_name":"Janet",
      "last_name":"Weaver",
      "avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
   }
}


//The response of the above APi is {"data":{"id":2,"email":"janet.weaver@reqres.in","first_name":"Janet","last_name":"Weaver","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"}}
Note:Here Data Node is having further Nested JSON, so we will need to Create Two Class Data and Users (that will have id, email, first_name etc.)

First Class

public class Data {

    private Users data;

    public Users getData() {
        return data;
    }

    public void setData(Users data) {
        this.data = data;
    }

}

Second Class


public class Users {

    private Integer id;
    private String email;
    private String first_name;
    private String last_name;
    private String avatar;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return first_name;
    }

    public void setFirstName(String firstName) {
        this.first_name = firstName;
    }

    public String getLastName() {
        return last_name;
    }

    public void setLastName(String lastName) {
        this.last_name = lastName;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

}



Example Of Test Case

@Test
    public void FirstTestcase() throws IOException {
        String baseURL = "https://reqres.in/api/users/2";

        //The response of the above APi is {"data":{"id":2,"email":"janet.weaver@reqres.in","first_name":"Janet","last_name":"Weaver","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"}}
        // Here Data Node is having further Nested JSON, so we will need to Create Two Class Data and Users

        Response response = given()
                .get(baseURL)
                .then()
                .extract().response();

        System.out.println("The response of the above APi is " + response.asString());

        String bodyString = response.asString();

        System.out.println("Here-->" + bodyString.contains("Janet"));
        //Using JSONPath
        JsonPath jsonPath = response.jsonPath();

        int temp = jsonPath.get("data.id");

        System.out.println("id-->" + temp);
        System.out.println("using Path-->" + response.path("data.id"));
        System.out.println("using JsoNPath-->" + response.jsonPath().get("data.id"));

        ObjectMapper mapper = new ObjectMapper();
        //1) Configure Jackson’s ObjectMapper to not fail when encounger unknown properties
        //You can do this by disabling DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES property of ObjectMapper as shown below:

        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

       // We are deserialization using Object Mapper and mapping it to Data Class first after that we can get Details from Users class
        Data data = mapper.readValue(response.asString(), Data.class);
        // getAvatar is function of Users Class so once we Map Objects to Data Class we can directly use getAvatar
        System.out.println("Here Avatar-->" + data.getData().getAvatar());

        System.out.println("Here Email-->" + data.getData().getEmail());

    }


When Sample API Response is ArrayList

[{
"id": "1",
"employee_name": "",
"employee_salary": "0",
"employee_age": "0",
"profile_image": ""
}
.
.
.
.
{
"id": "217089",
"employee_name": "Altomdsde234234trik18805",
"employee_salary": "123",
"employee_age": "23",
"profile_image": ""
}]


Note: Here it is ArrayList in response

       List<Employee> employeeList = Arrays.asList(mapper.readValue(response.asString(), Employee[].class));

So we will Make Employee Class

public class Employee {

    private String id;
    private String employee_name;
    private String employee_salary;
    private String employee_age;
    private String profile_image;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getEmployee_name() {
        return employee_name;
    }

    public void setEmployee_name(String employee_name) {
        this.employee_name = employee_name;
    }

    public String getEmployee_salary() {
        return employee_salary;
    }

    public void setEmployee_salary(String employee_salary) {
        this.employee_salary = employee_salary;
    }

    public String getEmployee_age() {
        return employee_age;
    }

    public void setEmployee_age(String employee_age) {
        this.employee_age = employee_age;
    }

    public String getProfile_image() {
        return profile_image;
    }

    public void setProfile_image(String profile_image) {
        this.profile_image = profile_image;
    }

}


 @Test
    public void EmployeeMessageBody() throws IOException {
        String baseURL = "http://dummy.restapiexample.com/api/v1/employees";
    
       // Response is in ArrayList
        Response response = given()
                .get(baseURL)
                .then()
                .extract().response();

        System.out.println("The response of the above APi is " + response.asString());

        String bodyString = response.asString();

        System.out.println("Here-->" + bodyString.contains("216333"));

        //
        JsonPath jsonPath = response.jsonPath();

        String temp = jsonPath.get("id[0]");

        System.out.println("id-->" + temp);
        System.out.println("using Path-->" + response.path("id[1]"));
        System.out.println("using JsoNPath-->" + response.jsonPath().get("id[1]"));

        ObjectMapper mapper = new ObjectMapper();

        //Important make sure all they POJO elements should be same as per JSON response like name of all the keys exact match should be there otherwise exception would come wile mapping Objects using Jackson

        //1) Configure Jackson’s ObjectMapper to not fail when encounger unknown properties
        //You can do this by disabling DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES property of ObjectMapper as shown below:
       // mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //If the respone is in form of List
        List<Employee> employeeList = Arrays.asList(mapper.readValue(response.asString(), Employee[].class));

        System.out.println("Employee size-->"+employeeList.size());
        for (int i = 0; i < employeeList.size(); i++) {
            System.out.println("Here Id"+" of -->"+i+" "+ employeeList.get(i).getId());
            System.out.println("Here Employee Salary"+" of -->"+i+" "+  employeeList.get(i).getEmployee_salary());
            System.out.println("Here Employee Name"+" of -->"+i +" "+  employeeList.get(i).getEmployee_name());
        }



    }


Other Ways

  //Deserialization ArrayList JSON Using JSON Path
        List<Employee> employees=response.jsonPath().getList("",Employee.class);

AND

 //Deserialization Using Object Mapper
        ObjectMapper objectMapper=new ObjectMapper();

        ObjectReader objectReader = objectMapper.reader().withType(new TypeReference<List<Employee>>(){});

        List<Employee> employeeList = objectReader.readValue(response.asString());

 @Test
    public void EmployeeMessageBody() throws IOException {
        String baseURL = "http://dummy.restapiexample.com/api/v1/employees";
       // Response is in ArrayList
        Response response = given()
                .get(baseURL)
                .then()
                .extract().response();

        System.out.println("The response of the above APi is " + response.asString());

        String bodyString = response.asString();

        System.out.println("Here-->" + bodyString.contains("216333"));

        //
        JsonPath jsonPath = response.jsonPath();

   
        //Deserialization ArrayList JSON Using JSON Path
        List<Employee> employees=response.jsonPath().getList("",Employee.class);

        System.out.println(employees.size());
        System.out.println(employees.get(0).getEmployee_age());

        //Deserialization Using Object Mapper
        ObjectMapper objectMapper=new ObjectMapper();

        ObjectReader objectReader = objectMapper.reader().withType(new TypeReference<List<Employee>>(){});

        List<Employee> employeeList = objectReader.readValue(response.asString());
        System.out.println(employeeList.size());
        System.out.println(employeeList.get(0).getEmployee_age());
     
    }

When Sample API Response is Simple JSON

{
"id": "1",
"employee_name": "",
"employee_salary": "0",
"employee_age": "0",
"profile_image": ""
}


We will use 

Employee employee = mapper.readValue(response.asString(), Employee.class);

Print Preety JSON

private static String getPrettyJson(EncryptedMessage encryptedMessage) {
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    JsonParser jp = new JsonParser();
    JsonElement je = jp.parse(getDecryptedJsonPayload(encryptedMessage));
    return gson.toJson(je);

}


Using Jackson

Convert Java object to JSON, writeValue(...)  (Here we will use WriteValue whenever we want JSON use writeValue)

ObjectMapper mapper = new ObjectMapper();
Staff obj = new Staff();

//Object to JSON in file
mapper.writeValue(new File("c:\\file.json"), obj);

//Object to JSON in String
String jsonInString = mapper.writeValueAsString(obj);


Convert JSON to Java object, readValue(...)// As Json is already there we will use ReadValue to read Json

ObjectMapper mapper = new ObjectMapper();

//JSON from file to Object
Staff obj = mapper.readValue(new File("c:\\file.json"),Data.class);

//JSON from URL to Object
Staff obj = mapper.readValue(new URL("http://xyz.com/staff.json"), Data.class);

//JSON from String to Object
Staff obj = mapper.readValue(jsonInString, Data.class);


Java Object to JSON  (Here we will use WriteValue whenever we want JSON use writeValue)

Convert a Data object into a JSON formatted string.

  Data data= createDummyObject();

                 try {
                          // Convert object to JSON string and save into a file directly
                          mapper.writeValue(new File("D:\\data.json"), data);

                          // Convert object to JSON string
                          String jsonInString = mapper.writeValueAsString(data);
                          System.out.println(jsonInString);

                          // Convert object to JSON string and pretty print
                          jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
                          System.out.println(jsonInString);

                 } catch (JsonGenerationException e) {
                          e.printStackTrace();
                 } catch (JsonMappingException e) {
                          e.printStackTrace();
                 } catch (IOException e) {
                          e.printStackTrace();
                 }

JSON to Java Object (As Json is already there we will use ReadValue to read Json)

// Convert JSON string from file to Object
                          Staff staff = mapper.readValue(new File("D:\\staff.json"), Staff.class);
                          System.out.println(staff);

                          // Convert JSON to Object
                          Staff staff1 = mapper.readValue(new File("D:\\staff.json"), Staff.class);
                          System.out.println(staff1);

                          //Pretty print
                          String prettyStaff1 = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(staff1);
                          System.out.println(prettyStaff1);

                 } catch (JsonGenerationException e) {
                          e.printStackTrace();
                 } catch (JsonMappingException e) {
                          e.printStackTrace();
                 } catch (IOException e) {
                          e.printStackTrace();

                 }

9 comments: