Autobiographical link in Gson

I'm having some problems deserializing the Json array that follows this format:

[
{
  "ChildList":[
     {
        "ChildList":[

        ],
        "Id":110,
        "Name":"Books",
        "ApplicationCount":0
     }
  ],
  "Id":110,
  "Name":"Books",
  "ApplicationCount":0
}
]

Basically it is an array of categories, where each category can also have a list of subcategories, etc. etc. My class model looks something like this:

public class ArrayOfCategory{
    protected List<Category> category;
}

public class Category{

    protected ArrayOfCategory childList;
    protected int id;
    protected String name;
    protected int applicationCount;
}

Now, obviously, Gson is complaining about the circular link. Is there a way to parse this Json input, given that I cannot guess how many levels of categories there are? Thanks in advance.

Edit: , - , , , . , , JSON, (, Category ArrayOfCategory ). , , "deserializeJson (jsonString, ArrayOfCategory.class)", , .

private <T> T deserializeJson(String stream, Class<T> clazz) throws PluginException {
    try {
        JsonElement je = new JsonParser().parse(stream);
        if (je instanceof JsonArray) {
            return deserializeJsonArray(clazz, je);
        } else {
            return new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create().fromJson(stream, clazz);         
        }
    } catch (Exception e) {
        throw new PluginException("Failed to parse json string: " + ((stream.length() > 20) ? stream.substring(0, 20) : stream) + "... to class " + clazz.getName());
    }       
}

private <T> T deserializeJsonArray(Class<T> clazz, JsonElement je) throws InstantiationException, IllegalAccessException {
    ParameterizedType listField = (ParameterizedType) clazz.getDeclaredFields()[0].getGenericType();
    final Type listType = listField.getActualTypeArguments()[0];
    T ret = clazz.newInstance();
    final Field retField = ret.getClass().getDeclaredFields()[0];
    retField.setAccessible(true);
    retField.set(ret, getListFromJsonArray((JsonArray) je,(Class<?>) listType));
    return ret;
}

private <E> List<E> getListFromJsonArray(JsonArray je, Class<E> listType) {
    Type collectionType = new TypeToken<List<E>>(){}.getType();
    final GsonBuilder builder = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE);
    Gson jsonParser = builder.create();
    return jsonParser.fromJson(je, collectionType);
}
+5
2

, :

    com.google.gson.Gson gson = new GsonBuilder().create();
    InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("/tmp/gson.txt")));
    Collection<Category> fromJson = gson.fromJson(reader, new TypeToken<Collection<Category>>() {}.getType());
    System.out.println(fromJson);

.

"": new TypeToken<Collection<Category>>() {}.getType()

:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.List;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

public class GsonCircularReference {

    public class Category {
        protected List<Category> childList;
        protected int id;
        protected String name;
        protected int applicationCount;

        public List<Category> getChildList() {
            return childList;
        }

        public void setChildList(final List<Category> childList) {
            this.childList = childList;
        }

        public int getId() {
            return id;
        }

        public void setId(final int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public int getApplicationCount() {
            return applicationCount;
        }

        public void setApplicationCount(final int applicationCount) {
            this.applicationCount = applicationCount;
        }

        @Override
        public String toString() {
            return "Category [category=" + childList + ", id=" + id + ", name=" + name + ", applicationCount="
                    + applicationCount + "]";
        }

    }

    public static void main(final String[] args) throws JsonSyntaxException, JsonIOException, FileNotFoundException {
        com.google.gson.Gson gson = new GsonBuilder().create();
        InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("/tmp/gson.txt")));
        Collection<Category> fromJson = gson.fromJson(reader, new TypeToken<Collection<Category>>() {}.getType());
        System.out.println(fromJson);
    }

}

JSON:

[
{
  "childList":[
     {
        "childList":[
        ],
        "id":110,
        "Name":"Books",
        "applicationCount":0
     }
  ],
  "id":110,
  "name":"Books",
  "applicationCount":0
}
]
+2
+1

All Articles