Search code examples
json-deserializationrest-assuredpojojson-serialization

Java RestAssured API POJO Class Cannot deserialize value of type `POJO.Category` from Array value (token `JsonToken.START_ARRAY`)


I have created couple of POJO classes for serializing/deserializing. When I create a request to receive all categories I am expecting to receive an array of category objects. But I am getting the following error:-

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type POJO.Categories from Array value (token JsonToken.START_ARRAY)

See classes below:-

Category Class:-

package POJO;

public class Category {
    String _id;
    String name;
    Integer __v;
    String color;
    String icon;
    String id;
    
    public String get_id() {
        return _id;
    }
    public void set_id(String _id) {
        this._id = _id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer get__v() {
        return __v;
    }
    public void set_v(Integer __v) {
        this.__v = __v;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getIcon() {
        return icon;
    }
    public void setIcon(String icon) {
        this.icon = icon;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

}

Categories Class:-

package POJO;

import java.util.ArrayList;
import java.util.List;

public class Categories {
    ArrayList<Category> categories;

    public ArrayList<Category> getCategories() {
        return categories;
    }

    public void setCategory(ArrayList<Category> categories) {
        this.categories = categories;
    }
}

See my test class below:-

    import io.restassured.RestAssured;
    import io.restassured.parsing.Parser;
    import io.restassured.path.json.JsonPath;
    import io.restassured.response.Response;
    
    import static io.restassured.RestAssured.*;
    import static org.hamcrest.Matchers.*;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.testng.Assert;
    
    import POJO.Categories;
    import POJO.Category;

public class c_GetCategoryUsingPOJOClass {
    
    public static void main(String[] args) {
        
        RestAssured.baseURI = "https://eshop-backend-101.herokuapp.com/api/v1/";
        String getCategoriesResource = "categories";
            
            
            // Get all Categories
            Categories categoriesRes = given().log().all()

                .header("Content-Type", "application/json")
                .expect().defaultParser(Parser.JSON)
                
                .when().get(getCategoriesResource).as(Categories.class);
                
                // print the category name
                System.out.println("Categories:- ");
                System.out.println(categoriesRes);
    }

}

Further information - When using postman to connect to the GET Categories end point this is a response body I receive:-

[
    {
        "_id": "5f15d467f3a046427a1c26e1",
        "name": "Mobile",
        "__v": 0,
        "color": "#6e4035",
        "icon": "mobile",
        "id": "5f15d467f3a046427a1c26e1"
    },
    {
        "_id": "5f15d5b2cb4a6642bddc0fe7",
        "name": "House",
        "__v": 0,
        "color": "#E2E1F0",
        "icon": "home",
        "id": "5f15d5b2cb4a6642bddc0fe7"
    },
    {
        "_id": "5f9d7e938680aa1d979d7e19",
        "name": "Games",
        "__v": 0,
        "color": "#ffb8b8",
        "icon": "sun",
        "id": "5f9d7e938680aa1d979d7e19"
    },
    {
        "_id": "5f15d54cf3a046427a1c26e3",
        "name": "Computers",
        "__v": 0,
        "color": "#E1F0E7",
        "icon": "desktop",
        "id": "5f15d54cf3a046427a1c26e3"
    },
    {
        "_id": "5f15d545f3a046427a1c26e2",
        "name": "Beauty",
        "__v": 0,
        "color": "#F0E8DE",
        "icon": "palette",
        "id": "5f15d545f3a046427a1c26e2"
    },
    {
        "_id": "608fe08365074604f45ce544",
        "name": "Cameras",
        "icon": "camera",
        "color": "#ede4da",
        "__v": 0,
        "id": "608fe08365074604f45ce544"
    }
]

I have now updated by test class as follows:-

import POJO.Category;
import io.restassured.RestAssured;
import io.restassured.common.mapper.TypeRef;
import io.restassured.parsing.Parser;

public class c_GetCategoryUsingPOJOClass {
    
    public static void main(String[] args) {
        
        RestAssured.baseURI = "https://eshop-backend-101.herokuapp.com/api/v1/";
        String getCategoriesResource = "categories";
            
            
            // Get all Categories
            List<Category> categoriesRes = given().log().all()

                .header("Content-Type", "application/json")
                .expect().defaultParser(Parser.JSON)
                
                .when().get(getCategoriesResource).as(new TypeRef<List<Category>>() {});
                
                // print the category name
                System.out.println("Categories:- ");
                System.out.println(categoriesRes);
                System.out.println(categoriesRes.get(0).toString());

    }

}

Solution

  • The problem here is with your POJO, it will match to json structure:

    {
      "categories": [
        {...},
        {...}
      ]
    }
    

    but your json structure is

    [
        {...},
        {...}
    ]
    

    --> you just remove Categories class and change the way you deserialize json, mapping to List<Category>

    List<Category> as = given()...as(new TypeRef<List<Category>>() {});
    System.out.println(as);
    

    One more thing, override toString method before print the object.