Getting exception as Cannot deserialize value of type `response.BookingIDList` from Array value (token `JsonToken.START_ARRAY`)

Viewed 11111
I am trying to deserialize the response using POJO classes.
My sample response is;

[ { "bookingid": 4 }, { "bookingid": 9 }, { "bookingid": 3 }, { "bookingid": 2 }, { "bookingid": 1 }, { "bookingid": 6 }, { "bookingid": 5 }, { "bookingid": 10 }, { "bookingid": 8 }, { "bookingid": 7 } ]

    public class BookingID
    {
        private int bookingid;
    
        public void setId(int bookingid) {
            this.bookingid = bookingid;
        }
    
        public int getId() {
            return bookingid;
        }
    
        @Override
        public String toString() {
            return "BookingID{" +
                    "bookingid=" + bookingid +
                    '}';
        }

}

BookingList class

import java.util.List;

public class BookingIDList
{
    private List<BookingID> bookingList;

    public void setBookingList(List<BookingID> bookingList) {
        this.bookingList = bookingList;
    }

    public List<BookingID> getBookingList() {
        return bookingList;
    }

    @Override
    public String toString() {
        return "BookingIDList{" +
                "bookingList=" + bookingList +
                '}';
    }
}


**I am now trying to deserialize** 

Response response= given(requestSpecificationGenerator.GetRequestSpecification()).get("/booking"); System.out.println("All bookings are as follows \n"+response.asPrettyString());

    BookingIDList bookingIDList = response.getBody().as(BookingIDList.class);
**getting the exception here as**
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `response.BookingIDList` from Array value (token `JsonToken.START_ARRAY`)
 at [Source: (String)"[
    {
        "bookingid": 4
    },
    {
        "bookingid": 9
    },
    {
        "bookingid": 3
    },
    {
        "bookingid": 2
    },
    {
        "bookingid": 1
    },
    {
        "bookingid": 6
    },
    {
        "bookingid": 5
    },
    {
        "bookingid": 10
    },
    {
        "bookingid": 8
    },
    {
        "bookingid": 7
    }
]"; line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
2 Answers

the warning points out that it expects an object, not a collection/array, based on the BookingIDList POJO definition it would be something like:

{"bookingList": [ { "bookingid": 4 }, { "bookingid": 9 }, { "bookingid": 3 }, { "bookingid": 2 }, { "bookingid": 1 }, { "bookingid": 6 }, { "bookingid": 5 }, { "bookingid": 10 }, { "bookingid": 8 }, { "bookingid": 7 } ] }

I guess you don't want that, so instead of as(Class cls), you may want to use as.(TypeRef )

 /**
     * Get the body as a container with a generic type. Note that this may not work for JAXB (XML) or HTML.
     *
     * @return The object
     */
    <T> T as(TypeRef<T> typeRef);
List<BookingID> bookingIds = response.getBody().as(new TypeRef<List<BookingID>>() {
        });

Try something like this. As you are giving a direct json array, you have to use TypeFactory

String  t = "[{\"bookingid\":4},{\"bookingid\":9},{\"bookingid\":3},{\"bookingid\":2},{\"bookingid\":1},{\"bookingid\":6},{\"bookingid\":5},{\"bookingid\":10},{\"bookingid\":8},{\"bookingid\":7}]";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
JavaType type = mapper.getTypeFactory().constructParametrizedType(List.class, List.class, BookingID.class);
List<BookingID> t2 = mapper.readValue(t,type);
// just for printing
System.out.println(t2.size());
for( BookingID b1 : t2 ) {
    System.out.println(b1.getId());
}

Below is an example if you directly want to populate the pojo. Below is how the json should look. this is just for information.

String t = "{\"bookingList\":[{\"bookingid\":4},{\"bookingid\":9},{\"bookingid\":3},{\"bookingid\":2},{\"bookingid\":1},{\"bookingid\":6},{\"bookingid\":5},{\"bookingid\":10},{\"bookingid\":8},{\"bookingid\":7}]}";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
BookingIDList t1 = mapper.readValue(t, BookingIDList.class);
System.out.println(t1.getBookingList().size());

Here are the POJOs for either case

public class BookingID {
    @JsonProperty("bookingid")
    private int bookingid;

    public void setId(int bookingid) {
        this.bookingid = bookingid;
    }

    public int getId() {
        return bookingid;
    }

    @Override
    public String toString() {
        return "BookingID{" + "bookingid=" + bookingid + '}';
    }
}



public class BookingIDList {
    @JsonProperty( "bookingList" )
    private List<BookingID> bookingList;

    public void setBookingList(List<BookingID> bookingList) {
        this.bookingList = bookingList;
    }

    public List<BookingID> getBookingList() {
        return bookingList;
    }

    @Override
    public String toString() {
        return "BookingIDList{" + "bookingList=" + bookingList + '}';
    }
}
Related