【问题标题】:Android retrofit 2.0 parse json using GsonAndroid 改造 2.0 使用 Gson 解析 json
【发布时间】:2016-02-25 06:27:41
【问题描述】:

我使用改造 2.0 库从 web 服务收到以下 json 响应。由于改造在内部默认使用 Gson 将 json 映射到 Java 对象。

[
    {
        "album-96": {
            "id": 96,
            "m_id": 1,
            "user_id": null,
            "p_id": null,
            "category_id": 1,
            "sub_category_id": 12,
            "country_id": 226,
            "menu_id": null,
            "name": "Kate Gosselin Photos",
            "old_name": "Kate Gosselin Photos",
            "meta_description": "Katie Irene "Kate" Gosselin is an American television personality",
            "meta_keywords": "Television, Personality",
            "tags": "",
            "description": "<p>Katie Irene "Kate" Gosselin is an American television personality</p>",
            "total_file": 18,
            "view": 330,
            "url_str": "kate-gosselin-photos-96",
            "url": "/album/kate-gosselin-photos-96",
            "custom_url": "/album/96/kate-gosselin-photos",
            "old_url": "kate-gosselin-photos-96.html",
            "created_date": 1440843034,
            "update_date": 1440866729,
            "old": "no",
            "status": "publish",
            "c_id": 226,
            "c_name": "United States",
            "c_url": "united-states",
            "ca_id": 1,
            "ca_name": "Actress",
            "ca_url": "actress",
            "sca_id": 12,
            "sca_categories_id": 1,
            "sca_name": "Television",
            "sca_url": "television",
            "array": [
                {
                    "id": 5359,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate Gosselin",
                    "name": "5359.jpg",
                    "custom_url": "/photo/5359/kate-gosselin"
                },
                {
                    "id": 5358,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate Gosselin",
                    "name": "5358.jpg",
                    "custom_url": "/photo/5358/kate-gosselin"
                },
                {
                    "id": 5357,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate Gosselin",
                    "name": "5357.jpg",
                    "custom_url": "/photo/5357/kate-gosselin"
                },
                {
                    "id": 5356,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate gosselin",
                    "name": "5356.jpg",
                    "custom_url": "/photo/5356/kate-gosselin"
                },
                {
                    "id": 5355,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate Gosselin hair",
                    "name": "5355.jpg",
                    "custom_url": "/photo/5355/kate-gosselin-hair"
                },
                {
                    "id": 5354,
                    "album_path": "/site-content/albums/Kate-Gosselin-Photos/",
                    "title": "Kate gosselin",
                    "name": "5354.jpg",
                    "custom_url": "/photo/5354/kate-gosselin"
                }
            ]
        },
        "album-95": {
            "id": 95,
            "m_id": 1,
            "user_id": null,
            "p_id": null,
            "category_id": 4,
            "sub_category_id": 6,
            "country_id": 226,
            "menu_id": null,
            "name": "Christina Maria Aguilera",
            "old_name": "Christina Maria Aguilera",
            "meta_description": "Christina María Aguilera is an American singer, songwriter, and actress. Born in Staten Island, New York and raised in Rochester and Wexford, Pennsylvania",
            "meta_keywords": "Christina Maria Aguilera",
            "tags": "",
            "description": "<p>Christina María Aguilera is an American singer, songwriter, and actress. Born in Staten Island, New York and raised in Rochester and Wexford, Pennsylvania</p>",
            "total_file": 45,
            "view": 466,
            "url_str": "christina-maria-aguilera-95",
            "url": "/album/christina-maria-aguilera-95",
            "custom_url": "/album/95/christina-maria-aguilera",
            "old_url": "christina-maria-aguilera-95.html",
            "created_date": 1435346180,
            "update_date": 1435346329,
            "old": "no",
            "status": "publish",
            "c_id": 226,
            "c_name": "United States",
            "c_url": "united-states",
            "ca_id": 4,
            "ca_name": "Music",
            "ca_url": "music",
            "sca_id": 6,
            "sca_categories_id": 4,
            "sca_name": "Singer",
            "sca_url": "singer",
            "array": [
                {
                    "id": 5334,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5334.jpg",
                    "custom_url": "/photo/5334/christina-aguilera"
                },
                {
                    "id": 5333,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5333.jpg",
                    "custom_url": "/photo/5333/christina-aguilera"
                },
                {
                    "id": 5332,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5332.jpg",
                    "custom_url": "/photo/5332/christina-aguilera"
                },
                {
                    "id": 5331,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5331.jpg",
                    "custom_url": "/photo/5331/christina-aguilera"
                },
                {
                    "id": 5330,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5330.jpg",
                    "custom_url": "/photo/5330/christina-aguilera"
                },
                {
                    "id": 5329,
                    "album_path": "/site-content/albums/Christina-Maria-Aguilera/",
                    "title": "Christina Aguilera",
                    "name": "5329.jpg",
                    "custom_url": "/photo/5329/christina-aguilera"
                }
            ]
        }
    }
]

我使用http://www.jsonschema2pojo.org/ 为我的 json 生成模型类。但它不会返回 Arraylist 中的项目列表。以下是我的代码

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://girlvalue.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GirlValueAPI girlValueAPI = retrofit.create(GirlValueAPI.class);
        Call<AlbumsList> call = girlValueAPI.loadAlbums("android");
        call.enqueue(this);

上述 json 响应的模型类应该是什么?

【问题讨论】:

  • “Retrofit 默认在内部使用 Gson 将 json 映射到 Java 对象” - 不,Retrofit 2.0 不再是这种情况。 指示它使用 Gson。 “但它没有返回 Arraylist 中的项目列表” - 那么它返回的是什么?至少您可以提供您当前拥有的模型。还要记住,Retrofit 1.x 和 2.0 之间的 url 解析方式不同。只是提到它,以防您的 api 基本 url 在其路径中有版本信息。

标签: android json gson retrofit


【解决方案1】:

不幸的是,您的 JSON 结构相当复杂。你可以走两条路。 首先:为每个专辑创建一个包含字段的类。弱点:如果出现更多专辑,应用会崩溃!

class BaseResponse {
@SerializedName("album-96")
Album album96;

@SerializedName("album-95")
Album album95;

private class Album{

    AlbumItem[] array;
    Integer id;
//all of the other fields for Album...
        }
}

另一种选择是两个使用自定义反序列化器

public AlbumDeserializer implements JsonDeserializer<Album>
{
    @Override
    public Album deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
    {
//JSONElement here is your basic JSONArray retrieved from server.
        Album album = new Album();
        String data = json.getAsString();
        List<String> albums = Arrays.asList(data.split(" "));

        //check if string contains part like album-96 or album-95, or album+ number, using java regex. Work with that string.
    }
}

【讨论】:

  • 然后使用第二个选项
【解决方案2】:

您在 JSON 结构中没有顶级字段。它以数组开头。试试这个:

Call&lt;AlbumsList[]&gt; call = girlValueAPI.loadAlbums("android");

并获取loadAlbums(..) 方法返回一个数组类型。

【讨论】:

  • AlbumList[]的结构应该是什么?
  • 抱歉,我认为您不应该将其读入AlbumsList[]。将其读入List&lt;JsonElement&gt;。当您遍历这些元素的列表时,获取与该顶级键关联的JsonElement(因为它们可以不同 - 在您的示例中为专辑 96 和专辑 95)并将其读入专辑。通过在迭代每个 JsonElement 时创建 new Album() 来创建 List&lt;Album&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多