0

Hello i was trying to deserialize the following JSON response from a Web Api:

{
    "response": [
        370968,
        {
            "aid": 65843156,
            "owner_id": 17519165,
            "artist": "Bass Test",
            "title": "дурной басс!",
            "duration": 238,
            "url": "http://cs6-10v4.vk-cdn.net/p22/c412a04df93035.mp3?extra=9YguhLftfZDDwo4JKBVwvlx_V1vwlu5pNU4-WremEqM9bL8eN2vh3_qu7bAg9EgNCj0ztEcMurarC499x8X2MpUaipykG2LDueWe0QQMrIPplkxKdV1xcQp35baDwA84l-luVxai9maX",
            "lyrics_id": "6214304"
        },
        {
            "aid": 207425918,
            "owner_id": 96085484,
            "artist": "► DJ Pleased",
            "title": "Bass Test № 04 (New 2013)",
            "duration": 328,
            "url": "http://cs6-7v4.vk-cdn.net/p23/6d7071221fb912.mp3?extra=O5ih5W5YkaEkXhHQSOKeDzvtr0V8xyS1WhIgjYLROFOMcW__FpU3mSf5udwdEAq6kkcz7QSy5jB57rTgSxnRJXCySZy2b0J_a2DvzFUBqVX6lcKqlarTryP_loQyk-SYPbFLh-9mSzm_iA",
            "lyrics_id": "86651563",
            "genre": 10
        }
    ]
}

My intention is to build a class to get the items in the response and use them in my Java Android application. The problem is that the first item of the response array is a number and not an object like the next items. So when I parse it with Gson it gives me the error:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]

I used the retrofit android library with the following POJO class (witch works if i don't have the counter in the response):

import java.util.HashMap;
import java.util.Map;

public class Response {

private Integer aid;
private Integer ownerId;
private String artist;
private String title;
private Integer duration;
private String url;
private String lyricsId;
private Integer genre;
private String album;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

/**
 *
 * @return
 * The aid
 */
public Integer getAid() {
    return aid;
}

/**
 *
 * @param aid
 * The aid
 */
public void setAid(Integer aid) {
    this.aid = aid;
}

/**
 *
 * @return
 * The ownerId
 */
public Integer getOwnerId() {
    return ownerId;
}

/**
 *
 * @param ownerId
 * The owner_id
 */
public void setOwnerId(Integer ownerId) {
    this.ownerId = ownerId;
}

/**
 *
 * @return
 * The artist
 */
public String getArtist() {
    return artist;
}

/**
 *
 * @param artist
 * The artist
 */
public void setArtist(String artist) {
    this.artist = artist;
}

/**
 *
 * @return
 * The title
 */
public String getTitle() {
    return title;
}

/**
 *
 * @param title
 * The title
 */
public void setTitle(String title) {
    this.title = title;
}

/**
 *
 * @return
 * The duration
 */
public Integer getDuration() {
    return duration;
}

/**
 *
 * @param duration
 * The duration
 */
public void setDuration(Integer duration) {
    this.duration = duration;
}

/**
 *
 * @return
 * The url
 */
public String getUrl() {
    return url;
}

/**
 *
 * @param url
 * The url
 */
public void setUrl(String url) {
    this.url = url;
}

/**
 *
 * @return
 * The lyricsId
 */
public String getLyricsId() {
    return lyricsId;
}

/**
 *
 * @param lyricsId
 * The lyrics_id
 */
public void setLyricsId(String lyricsId) {
    this.lyricsId = lyricsId;
}

/**
 *
 * @return
 * The genre
 */
public Integer getGenre() {
    return genre;
}

/**
 *
 * @param genre
 * The genre
 */
public void setGenre(Integer genre) {
    this.genre = genre;
}

/**
 *
 * @return
 * The album
 */
public String getAlbum() {
    return album;
}

/**
 *
 * @param album
 * The album
 */
public void setAlbum(String album) {
    this.album = album;
}

public Map<String, Object> getAdditionalProperties() {
    return this.additionalProperties;
}

public void setAdditionalProperty(String name, Object value) {
    this.additionalProperties.put(name, value);
}

Is there any way to make it work? I don't have access to the API server so i cant change how the result is displayed. To generate the class i used http://www.jsonschema2pojo.org/ but i was able to generate it only by removing the counter from the response.

The wrapper class VKSongApi:

public class VKSongApi {

private List<Response> response = new ArrayList<Response>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

/**
 *
 * @return
 * The response
 */
public List<Response> getResponse() {
    return response;
}

/**
 *
 * @param response
 * The response
 */
public void setResponse(List<Response> response) {
    this.response = response;
}

public Map<String, Object> getAdditionalProperties() {
    return this.additionalProperties;
}

public void setAdditionalProperty(String name, Object value) {
    this.additionalProperties.put(name, value);
}

}

The retrofit interface class is:

public interface VKApi  {
@GET("/method/audio.search")
Call<VKSongApi> search(@Query("q") String query, @Query("access_token") String token);
}

Then in the MainActivity i do:

public static final String BASE_URL = "https://api.vk.com/method/";
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();
VKApi apiService =
        retrofit.create(VKApi.class);

And call the method from the MainActivity with:

    Call<VKSongApi> call = apiService.search("test","fff9ef502df4bb10d9bf50dcd62170a24c69e98e4d847d9798d63dacf474b674f9a512b2b3f7e8ebf1d69");
    call.enqueue(new Callback<VKSongApi>() {
        @Override
        public void onResponse(Call<VKSongApi> call, Response<VKSongApi> response) {
            int statusCode = response.code();
            VKSongApi song = response.body();
            Log.d(TAG,response.message());

        }

        @Override
        public void onFailure(Call<VKSongApi> call, Throwable t) {
            //Here the error occurs com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]
            Log.d(TAG,"Failure");
        }
    });
Bryan
  • 14,756
  • 10
  • 70
  • 125
  • It seems the issue is with the number 370968, please post your code for other class as well wrapping `Response` class – Umais Gillani Nov 20 '16 at 12:56
  • @UmaisGillani i added the rest of the code – Gr33nLight Nov 20 '16 at 13:25
  • @Gr33nLight The issue is with the response (370968) without key. You can not access the value without key in retrofit but manual parsing can be done . – iSrinivasan27 Nov 21 '16 at 06:06
  • Possible duplicate of [Gson Parse Json with array with different object types](http://stackoverflow.com/questions/14713736/gson-parse-json-with-array-with-different-object-types) – Bryan Nov 21 '16 at 20:44

1 Answers1

0

I solved by parsing manually the response using a custom deserializer class