• 6
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Parsing iterative json objects using retrofit/gson

I'm being sent something like the following from a server I'm required to connect to:

{
  "properties": {
    "prop1": {
      "type": "string",
      "title": "string"
    },
    "prop2": {
      "type": "string",
      "title": "string"
    },
    "prop3": {
      "type": "string",
      "title": "string"
    },
    "prop4": {
      "type": "string",
      "title": "string"
    }
  }
}

Obviously it would be more ideal for the server to send an array of objects with an id field, but I can't change it unfortunately. The numbers after "prop" can go up ad infinitum (though realistically won't go above 50 or so), is there a graceful way to handle this in Retrofit 2/GSON? or do I need to intercept this call and do it manually each time?

In a perfect world I'd like to end up with an array of "Prop" pojos that have an id field (1, 2, 3, etc), or even with "prop1", "prop2" etc in a field in each object.

Here is the hint for your question:

You have to create model class like:

public class PropertiesData {
    public ArrayList<Properties> properties = new ArrayList<>();

    //getters setters


    public ArrayList<Properties> getProperties() {
        return properties;
    }

    public void setProperties(ArrayList<Properties> properties) {
        this.properties = properties;
    }

    public class Properties {
        Map<String, SubProperties> subPropertiesMap = new HashMap<>();

        //getters setters

        public Map<String, SubProperties> getSubPropertiesMap() {
            return subPropertiesMap;
        }

        public void setSubPropertiesMap(Map<String, SubProperties> subPropertiesMap) {
            this.subPropertiesMap = subPropertiesMap;
        }
    }

    public class SubProperties {
        public String type;
        public String title;
        //getters setters

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }
}

You have to create custom Gson Builder:

    Gson gson_gd = new GsonBuilder().registerTypeAdapter(
            PropertiesData.class, new JsonDeserializer<PropertiesData>() {
                @Override
                public PropertiesData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    JsonObject elements= json.getAsJsonObject();
                    return new Gson().fromJson(elements,
                            PropertiesData.class);
                }
            }
    ).create();

And use it when you are building retrofit instance:

.setConverter(GsonConverterFactory.create(gson_gd)).build();

Everything I have created based on provided json.

Hope it will helps you.

  • 1
Reply Report
      • 2
    • This got me super close, in the deserializer I instantiated a new Properties class, then ran through all the keys in the json element and mapped them to the subPropertiesMap, and that did the trick! Thanks for your help.