diogojme
diogojme

Reputation: 2359

Cannot parse json with two different data types in retrofit 2.0

I'm trying to parse this json bellow, into a object named AlbumResponse that have another two objects inside, Album and PaginationInfo. Retrofit version 2.0

[
    {
        "id": "6",
        "name": "King Stays King",
        "artist_name":"Timbaland",
        "image":""
    },
    {
        "id": "7",
        "name": "East Atlanta Santa 2",
        "artist_name":"Gucci Mane",
        "image":""
    },
    {
        "id": "8",
        "name": "The cuban connect",
        "artist_name":"Phophit",
        "image":""
    },
    {
        "id": "9",
        "name": "Shmoney Keeps",
        "artist_name":"Calling",
        "image":""
    },
    {
        "id": "10",
        "name": "Cabin Fever 3",
        "artist_name":"Wiz khalifa",
        "image":""
    }
],
{
    "nextPage": "http://private-ede172-mymixtapez1.apiary-mock.com/features/page_3/",
    "itemsTotal": 10,
    "page": 2,
    "pagerMax": 2
}

Album class

public class Album {
    long id;
    String name;
    @SerializedName("artist_name")
    String artistName;
    String image;
}

PaginationInfo class

public class PaginationInfo {
    int page;
    int pagerMax;
    int nextPage;
    int itemsTotal;
}

AlbumResponse, that have both classes above inside, and Album is a List

public class AlbumResponse {
    public List<Album> albums;
    public PaginationInfo paginationInfo;
}

The request

Call<AlbumResponse> responseCall = albumService.features();
responseCall.enqueue(new Callback<AlbumResponse>() {
    @Override
    public void onResponse(Response<AlbumResponse> response, Retrofit retrofit) {
        if(response.isSuccess()) {
            AlbumResponse albumResponse = response.body();
            PaginationInfo paginationInfo = albumResponse.getPaginationInfo();

        }
        System.out.println();
    }

    @Override
    public void onFailure(Throwable t) {
        System.out.println(t.getMessage());
    }
});

Interface

public interface AlbumService {
  @GET("/features/")
  Call<AlbumResponse> features();
}

The problem is that im getting a Throwable that contains:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $`

Please, can someone help me, i not found any answers in stackoverflow. Thanks.

Upvotes: 2

Views: 1239

Answers (2)

iTSangar
iTSangar

Reputation: 462

Your JSON have a trouble in initial declaration.

According json.org:

JSON is built on two structures:

• A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

• An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Try update your JSON to:

"albums": [
    {
        "id": "6",
        "name": "King Stays King",
        "artist_name":"Timbaland",
        "image":""
    },
    {
        "id": "7",
        "name": "East Atlanta Santa 2",
        "artist_name":"Gucci Mane",
        "image":""
    },
    {
        "id": "8",
        "name": "The cuban connect",
        "artist_name":"Phophit",
        "image":""
    },
    {
        "id": "9",
        "name": "Shmoney Keeps",
        "artist_name":"Calling",
        "image":""
    },
    {
        "id": "10",
        "name": "Cabin Fever 3",
        "artist_name":"Wiz khalifa",
        "image":""
    }
],
"pagination_info": 
{
    "nextPage": "http://private-ede172-mymixtapez1.apiary-mock.com/features/page_3/",
    "itemsTotal": 10,
    "page": 2,
    "pagerMax": 2
}

Upvotes: 0

MoQ93
MoQ93

Reputation: 341

The error says: the Parser expected a JSON-Object but it reads a JSON-array. To fix it (if you control the server) you should change the JSON String to something like this:

{
  "albums" : [
    {
        "id": "6",
        "name": "King Stays King",
        "artist_name":"Timbaland",
        "image":""
    },
    {
        "id": "7",
        "name": "East Atlanta Santa 2",
        "artist_name":"Gucci Mane",
        "image":""
    },
    {
        "id": "8",
        "name": "The cuban connect",
        "artist_name":"Phophit",
        "image":""
    },
    {
        "id": "9",
        "name": "Shmoney Keeps",
        "artist_name":"Calling",
        "image":""
    },
    {
        "id": "10",
        "name": "Cabin Fever 3",
        "artist_name":"Wiz khalifa",
        "image":""
    }
],
 "paginationInfo" : {
    "nextPage": "http://private-ede172-mymixtapez1.apiary-mock.com/features/page_3/",
    "itemsTotal": 10,
    "page": 2,
    "pagerMax": 2
 }
}

Now it's a JSON-Object and is conform to your Java class.

If you cannot change the JSON on the backend, I would take it as row response and parse the albums Array and the PaginationInfo separately using GSON or manually.

Btw. you must change the nextPage type from int to String in the PaginationInfo class

Upvotes: 2

Related Questions