Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit: Handling JSON object that dynamically changes its name

I use retrofit.

I have JSON data like this:

{
"elements": {
    "159": {
        "id": 159,
        "name": "Alex"
        },
    "831": {
        "id": 831,
        "name": "Sofia"
        },
    "3125": {
        "id": 3125,
        "name": "Mark"
       }
    }
}

Structure of this JSON cannot be configured on my side.

And I want to handle those objects (that dynamically change their names) using retrofit.

I have sth like that now.

Model:

public class Elements{
public ArrayList<ElementsItem> = new Array<ElementsItem>();

//getters setters

public class ElementsItem{
    public ArrayList<ElementsItemDetails> = new Array<ElementsItemDetails>();

    //getters setters
}

public class ElementItemDetails{
    public Integer id;
    public String name;
    //getters setters
}}

API:

public interface MyApi {

@GET("/file.php?method=getElementDetails")
public void getDetails(@Query("ids") ArrayList<Integer> ids_list, Callback<Elements> callback);
}

And the function where I try to handle data:

public void get_details_for_particular_elements(ArrayList<Integer> ids_list){

    Gson gson_gd = new GsonBuilder().registerTypeAdapter(
            Elements.class,
            new JsonDeserializer<Elements>() {

                @Override
                public Elementsdeserialize(JsonElement je,
                        Type type, JsonDeserializationContext jdc)
                        throws JsonParseException {
                    // TODO Auto-generated method stub
                    Log.d("my_app", "Deserialization for Getting Elements Details in progress..");
                    JsonObject elements= je.getAsJsonObject();
                    return new Gson().fromJson(elements,
                            Elements.class);
                }

            }).create();

    RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)
    .setConverter(new GsonConverter(gson_gd)).build();


    MyApi myDetails = restAdapter.create(MyApi.class);

    myDetails.getDetails(ids_list, new Callback<Elements>() {

        @Override
        public void success(Elements e, Response response) {
            // TODO Auto-generated method stub

            Log.d("my_app", "Success! " + e.getElementsItem().get(0).getElementsItemDetails().get(0).getName());

        }

        @Override
        public void failure(RetrofitError retrofitError) {
            // TODO Auto-generated method stub
            Log.d("my_app", "Failure..." + retrofitError);
        }


    });
}

I try to handle the name "Alex" and print it in LogCat, but I cannot - application stops. I am sure that this command:

e.getElementsItem().get(0).getElementsItemDetails().get(0).getName()

is wrong, but I don't know any other way how to handle the name value.

How to behave when object name changes (in that case there are three similar objects called in dependance of list of ids ids_list provided? Here: [156,831,3125]

Please help.

like image 410
Jack Lynx Avatar asked Feb 10 '15 22:02

Jack Lynx


People also ask

How does dynamic JSON retrofit handle?

The prefix will change from string to object randomly in both success(...) and failure(...) methods! In above code POJO TrackerRefResponse. java prefix responseMessage is set to string or object of type responseMessage , so we can create the POJO with ref variable with same name (java basics :) )

How do I send a body in post request in retrofit?

Request Body@POST("users/new") Call<User> createUser(@Body User user); The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.

What is retrofit JSON?

What is Retrofit. Retrofit is a REST Client for Java and Android allowing to retrieve and upload JSON (or other structured data) via a REST based You can configure which converters are used for the data serialization, example GSON for JSON.

What is retrofit GSON?

Overview. Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.


1 Answers

As the key for you ElementItemDetails is dynamically generated, you should use a Map to represent the structure.

In your model class Elements:

Replace

public ArrayList<ElementsItem> = new Array<ElementsItem>();

with

Map<String, ElementItemDetails> elemDetails;

Hope this helps.

like image 89
Elisa Avatar answered Oct 22 '22 03:10

Elisa