Gson

registerTypeAdapter.

retrofit

gson-converter,

build.gradle

implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'

implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

retrofit,

converter-gson





{ "cars" : { "car_type" : "Hatchback" , "car_models" : { "car_name" : "Swift" , "power_window" : "yes" } } }

{ "cars" : { "car_type" : "Sedan" , "car_models" : [ { "car_name" : "Xcent" , "power_window" : "no" }, { "car_name" : "Ciaz" , "power_window" : "yes" } ]} }

cars_object_json.json

cars_array_json.json

registerTypeAdapter

So, first of all, go to http://www.jsonschema2pojo.org/

Paste the json https://navneet7k.github.io/cars_array_json.json in the box provided

Specify Target language as Java, Source Type as JSON and annotation style as Gson Now click preview and copy the generated java files Now copy the contents of the class and add it in android studio project





public class Cars { @SerializedName ( "car_type" ) @Expose private String carType ; @SerializedName ( "car_models" ) @Expose private List < CarModel > cardModels = null ; public String getCarType () { return carType ; } public void setCarType ( String carType ) { this . carType = carType ; } public List < CarModel > getCardModels () { return cardModels ; } public void setCardModels ( List < CarModel > cardModels ) { this . cardModels = cardModels ; } }

public class CarModel { @SerializedName ( "car_name" ) @Expose private String carName ; @SerializedName ( "power_window" ) @Expose private String powerWindow ; public String getCarName () { return carName ; } public void setCarName ( String carName ) { this . carName = carName ; } public String getPowerWindow () { return powerWindow ; } public void setPowerWindow ( String powerWindow ) { this . powerWindow = powerWindow ; } }

GsonBuilder b = new GsonBuilder (); b . registerTypeAdapter ( Cars . class , new JsonDeserializer < Cars >() { @Override public Cars deserialize ( JsonElement arg0 , Type arg1 , JsonDeserializationContext arg2 ) throws JsonParseException { JsonObject CarsObj = arg0 . getAsJsonObject (); JsonObject innerObj = CarsObj . getAsJsonObject ( "cars" ); Gson g = new Gson (); Cars a = g . fromJson ( arg0 , Cars . class ); List < CarModel > carModels = null ; if ( innerObj . get ( "car_models" ). isJsonArray ()) { carModels = g . fromJson ( innerObj . get ( "car_models" ), new TypeToken < List < CarModel >>() { }. getType ()); } else { CarModel single = g . fromJson ( innerObj . get ( "car_models" ), CarModel . class ); carModels = new ArrayList < CarModel >(); carModels . add ( single ); } a . setCardModels ( carModels ); return a ; } });

car_models

public class MainActivity extends AppCompatActivity { @Override protected void onCreate ( Bundle savedInstanceState ) { super . onCreate ( savedInstanceState ); setContentView ( R . layout . activity_main ); parseJson (); } private void parseJson () { GsonBuilder b = new GsonBuilder (); b . registerTypeAdapter ( Cars . class , new JsonDeserializer < Cars >() { @Override public Cars deserialize ( JsonElement arg0 , Type arg1 , JsonDeserializationContext arg2 ) throws JsonParseException { JsonObject CarsObj = arg0 . getAsJsonObject (); JsonObject innerObj = CarsObj . getAsJsonObject ( "cars" ); Gson g = new Gson (); Cars a = g . fromJson ( arg0 , Cars . class ); List < CarModel > carModels = null ; if ( innerObj . get ( "car_models" ). isJsonArray ()) { carModels = g . fromJson ( innerObj . get ( "car_models" ), new TypeToken < List < CarModel >>() { }. getType ()); } else { CarModel single = g . fromJson ( innerObj . get ( "car_models" ), CarModel . class ); carModels = new ArrayList < CarModel >(); carModels . add ( single ); } a . setCardModels ( carModels ); return a ; } }); Retrofit retrofit = new Retrofit . Builder () . baseUrl ( "https://navneet7k.github.io/" ) . addConverterFactory ( GsonConverterFactory . create ( b . create ())) . build (); RequestInterface request = retrofit . create ( RequestInterface . class ); Call < Cars > call1 = request . getJson (); call1 . enqueue ( new Callback < Cars >() { @Override public void onResponse ( Call < Cars > call , Response < Cars > response ) { Toast . makeText ( MainActivity . this , "Success!" , Toast . LENGTH_SHORT ). show (); } @Override public void onFailure ( Call < Cars > call , Throwable t ) { Toast . makeText ( MainActivity . this , "Failure" , Toast . LENGTH_SHORT ). show (); } }); } }

RequestInterface.java

cars_object_json.json

interface RequestInterface { @GET ( "cars_object_json.json" ) Call < Cars > getJson (); }

RequestInterface.java

cars_array_json.json

interface RequestInterface { @GET ( "cars_array_json.json" ) Call < Cars > getJson (); }

Response < Cars > response

We often come across issue where a json dynamically switches its type based on the response. For example, in normal cases suppose that you have a list of cars returned as an array from your backend, but when the number of cars in the list is one, you are given just an abject instead of array. In such cases, your code should be ready to handle the response no matter whether it is an array or an object.To handle such cases,provides plenty of customisation options. One such option isSo lets dive deeper to check how its done.In this tutorial we will be usingto make the network calls and of courseso go to your app leveland add the following as dependenciesplease add the latest dependency versions forNow check the following json strcutures that we will be parsingInyou can see that car_models is an object because there is only one item inside it whereas incar_models is an array since there are more than one items in it. We have to write a parser which could automatically identify the response format and parse both the cases easily.is exactly what we want here.Alright, lets see some code nowFirst of all, there are two type of object models or POJOs that we need to create for the above json >> Cars,CarModelsNow copy the classes Cars,CarModels fromand add it to your project like thisCars.javaCarModels.javaNow, create a deserializer like shown belowIn the above deserializer, you can clearly see that we have checked whetheris an array or an object and then parsed the response accordingly.Now go ahead and attach the converter to your retrofit implementation so that the entire code for your MainActivity.java will look like thisAnd yourforwill be like thisforwill be like thisBy this method you will get the correct response forin the retrofit callbacks even if your response changes dynamically.