У меня есть следующий json, который я хочу десериализовать:

{
    "locations": [{
        "id": 17,
        "account_id": 11,
        "name": "The Haunted Lexington",
        "radius": 100
    }]
}

(В данном конкретном случае есть только один Location, но их может быть много).

Я десериализую это с помощью Gson со следующим кодом:

Gson gson = new GsonBuilder().create();
LocationList ll = gson.fromJson(jsonString, LocationList.class);

У меня определены следующие классы:

public class Location {

    @SerializedName("id")
    private long mId;

    @SerializedName("account_id")
    private long mAccountId;

    @SerializedName("name")
    private String mName;

    @SerializedName("radius")
    private int mRadius;

    public long getId() {
        return mId;
    }

    public String getName() {
        return mName;
    }
}

А также:

public class LocationList {
    @SerializedName("locations")
    private List<Location> mLocations;
}

Дело в том, что у меня есть куча этих «фиктивных» классов, которые содержат один объект, представляющий собой список других объектов (например, UserList, MessageList и т. д...)

Что я хотел бы сделать, так это каким-то образом проанализировать приведенный выше json, чтобы я мог пропустить определение промежуточного определения класса LocationList, например:

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

// Use the same json as above, but skip defining the superfluous "LocationList" class
List<Location> ll = gson.fromJson(jsonString, "locations", ArrayList<Location>.class);

Есть ли способ сделать это, возможно, предоставив собственный десериализатор?

3
jwir3 29 Окт 2014 в 23:04

2 ответа

Я столкнулся с подобной проблемой не так давно, и решил ее так

// Parse the JSON response.
JSONArray jsonArray = new JSONArray(response);

List<Location> locations = new ArrayList<Location>();

/*
 * Create a Location object for every JSONObject in the response,
 * and add it to the list.
 */
for (int i = 0; i < jsonArray.length(); i++) {
    JSONObject jsonObject = jsonArray.getJSONObject(i);

    Location location = new Gson().fromJson(jsonObject.toString(),
            Location.class);
    locations.add(location);

Подход здесь состоит в том, чтобы перебрать каждое местоположение в массиве местоположений в JSON, извлекая их одно за другим, а затем добавляя их в список.

JSON, с которым я работал, имел список в качестве корневого объекта, поэтому вы, вероятно, не можете использовать этот JSONArray jsonArray = new JSONArray(response);. Что-то вроде этого может лучше подойти для вашей ситуации

JSONObject jsonObject = new JSONObject(jsonString);
JSONArray locationsJsonArray = jsonObject.get("locations");

Я не проверял эти последние 2 строки, но я думаю, что вы поняли идею.

Я надеюсь, что вы можете использовать это, чтобы решить вашу проблему.

0
Tim 29 Окт 2014 в 23:42

В настоящее время я использую простой метод для достижения вашей цели:

private static <T> List<T> getList(final String jsonVal, final String listTag, T t) {
    try {
        JsonObject jsonObject = (JsonObject)(new JsonParser()).parse(jsonVal); // root JsonObject. i.e. "locations"
        JsonArray jsonArray = (JsonArray)jsonObject.get(listTag);

        Gson gson = new GsonBuilder().create();
        List<T> list = gson.fromJson(jsonArray, new TypeToken<List<T>>() {}.getType());

        return list;
    } catch (Exception e) {
        throw new IllegalArgumentException("Unexpected json structure!", e);
    }
}

Пример использования:

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

String jsonString = "{\"locations\":[{\"id\":17,\"account_id\":11,\"name\":\"The Haunted Lexington\",\"radius\":100}]}";

List<Location> list = getList(jsonString, "locations", new Location());

Этот метод следует использовать для ваших других классов, таких как:

List<User> userList = getList(jsonString, "users", new User());
List<Message> messageList = getList(jsonString, "messages", new Message());
0
Devrim 30 Окт 2014 в 01:19