Carl-Emil Kjellstrand
Carl-Emil Kjellstrand

Reputation: 1243

deserialize json with gson

I'm trying to deserialize json from worldbank.com to a pojo without any success. The json looks like: [{"page":1,"pages":7,"per_page":"50","total":304},[{"id":"ABW","iso2Code":"AW","name":"Aruba","region":{"id":"LCN","value":"Latin America & Caribbean "},

and can be found via: http://api.worldbank.org/countries/?format=json

and im running into problems with gson telling me: WorldBankDemo: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 52 path $[1]

Any clues as to how i can solve this? Preferably without changing from gson since that is the lib used by the networking lib I'm using (retrofit)

 WorldBankDataService service = ServiceFactory.createRetrofitService(WorldBankDataService.class, WorldBankDataService.SERVICE_ENDPOINT);
        service.getCountries()
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<WorldBank[]>() {
                    @Override
                    public final void onCompleted() {
                        // do nothing
                    }

                    @Override
                    public final void onError(Throwable e) {
                        Log.e("WorldBankDemo", e.getMessage());
                    }

                    @Override
                    public final void onNext(WorldBank[] response) {
                        Log.d("TAG", "resp: "+response);
                        //mCardAdapter.addData(response);
                    }
                });


public class ServiceFactory {
/**
 * Creates a retrofit service from an arbitrary class (clazz)
 * @param clazz Java interface of the retrofit service
 * @param endPoint REST endpoint url
 * @return retrofit service with defined endpoint
 */
public static <T> T createRetrofitService(final Class<T> clazz, final 
String endPoint) {
        final RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(endPoint)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        T service = restAdapter.create(clazz);

        return service;
    }
}

public class WorldBank {
    int page;
    int pages;
    String per_page;
    int total;
    //Country[] countrys;
}

Upvotes: 1

Views: 595

Answers (5)

Swamy
Swamy

Reputation: 132

JSON is not constructed well(especially for auto parsing), Array can contain objects or arrays but not both at same level, in the above JSON structure it starts with Array in that the first element is an object and second element is an array, so this kind of JSON structure is not recommended for auto parsing, if at all you want to continue with same JSON response you can go for manual parsing or change response structure.

Upvotes: 2

Carl-Emil Kjellstrand
Carl-Emil Kjellstrand

Reputation: 1243

Decided to give up and use another api, the world bank api just sucks :(

Upvotes: 0

Sreehari
Sreehari

Reputation: 5655

You can use gson to customize using this dependency

compile 'org.immutables:gson:2.3.1'

But slightly different way while invoking the rest client

For instance .If we have to get a list of countries declare an interface

public interface GetAllAPI {
 @GET("/all")
   List<Country> getCountries();
 }

Now rest client will be

public List<Country> GetAllCountries() {

   Gson gson = new GsonBuilder().create();

   RestAdapter restAdapter = new RestAdapter.Builder()
   .setEndpoint(service_url)
   .setConverter(new GsonConverter(gson))
   .build();

   GetAllAPI service = restAdapter.create(GetAllAPI.class);

   List<Country> countrylist = service.getCountries();

   return countrylist;
 }

Getting the results from API will be

List<Country> countrylist = service.getCountries();

You have to customize this implementation for specific requirement. This is an idea how to implement Gson with Retrofit

Go through this for more clarification

Upvotes: 0

Rahul Sharma
Rahul Sharma

Reputation: 13633

try this way

Gson gson = new Gson();
String jsonOutput = "Your JSON String";
Type listType = new TypeToken<List<ApiResponse>>(){}.getType();
List<ApiResponse> posts = (List<ApiResponse>) gson.fromJson(jsonOutput, listType);

and ApiResponse is like

public  class ApiResponse{
WorldBank object1;
ArrayList<Country> objects2;
}

I haven't try this on my end, but it will be similar like that.

Upvotes: 0

drulabs
drulabs

Reputation: 3121

It's actually a JSON array. so you can't use class. try this:

YourPojo[] objects = gson.fromJson(jsonString, YourPojo[].class)

works like a charm

Upvotes: 0

Related Questions