Gson期望begin_object但是是字符串......但是值会在响应之间改变类型

时间:2017-12-13 17:22:14

标签: java android json retrofit2 gson

所以,我试图通过构建一个应用程序来学习android,其中我使用lastFm api来获取类似的歌曲。我将retrofit2与Gson和rxJava一起使用。

要读取json响应,我使用Pojo类。要首先获得类似的曲目,我必须搜索它(第一次api调用),然后我必须根据用户选择的api调用api。

有些POJO在这些来电之间很常见,所以我不必复制它们。

我的问题是,在第一次调用中,响应包含一个艺术家作为字符串(仅名称),而在第二个响应中,艺术家是一个对象。

显然,当我尝试阅读第一个回应时,Gson期待一个"艺术家"对象,但它得到一个字符串。我如何将它们都实现为一个POJO,作为" Track"?

这是我的代码,我希望我很清楚(当我试图解释时,我有一个问题......,好吧,我的问题)

public class Track implements Parcelable{

@SerializedName("name")
@Expose
private String name;
@SerializedName("playcount")
@Expose
private Integer mPlaycount;
@SerializedName("artist")
@Expose
private Artist artist; // If i make this a String, the first call works
@SerializedName("url")
@Expose
private String url;
@SerializedName("streamable")
@Expose
private Streamable streamable;
@SerializedName("listeners")
@Expose
private String listeners;
@SerializedName("match")
@Expose
private String match;
@SerializedName("image")
@Expose
private List<Image> image = new ArrayList<>();
@SerializedName("mbid")
@Expose
private String mbid;
@Expose
private String mediumImage;
// Getters, setter, parcelable methods etc.

JSon第一个响应示例(不是完整响应,只有一个结果) 响应来自lastFm api

{
"results": {
    "opensearch:Query": {
        "#text": "",
        "role": "request",
        "startPage": "1"
    },
    "opensearch:totalResults": "1637",
    "opensearch:startIndex": "0",
    "opensearch:itemsPerPage": "30",
    "trackmatches": {
        "track": [
            {
                "name": "Ich tu dir weh",
                "artist": "Rammstein",
                "url": "https://www.last.fm/music/Rammstein/_/Ich+tu+dir+weh",
                "streamable": "FIXME",
                "listeners": "198819",
                "image": [
                    {
                        "#text": "https://lastfm-img2.akamaized.net/i/u/34s/1a82cbe48f604d4c8325122b09d310ed.png",
                        "size": "small"
                    },
                    {
                        "#text": "https://lastfm-img2.akamaized.net/i/u/64s/1a82cbe48f604d4c8325122b09d310ed.png",
                        "size": "medium"
                    },
                    {
                        "#text": "https://lastfm-img2.akamaized.net/i/u/174s/1a82cbe48f604d4c8325122b09d310ed.png",
                        "size": "large"
                    },
                    {
                        "#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
                        "size": "extralarge"
                    }
                ],
                "mbid": "1752a3db-918e-43ba-b7ac-63bcc9a6433c"
            }
        ]
    },
    "@attr": {}
   }
}

JSon第二个响应示例(不是完整响应,只有一个结果) 响应来自lastFm api

{
"similartracks": {
    "track": [
        {
            "name": "Waidmanns Heil",
            "playcount": 1806826,
            "mbid": "e1e060e0-73e7-4939-ac80-635e8cba45a2",
            "match": 1,
            "url": "https://www.last.fm/music/Rammstein/_/Waidmanns+Heil",
            "streamable": {
                "#text": "0",
                "fulltrack": "0"
            },
            "duration": 213,
            "artist": {
                "name": "Rammstein",
                "mbid": "b2d122f9-eadb-4930-a196-8f221eeb0c66",
                "url": "https://www.last.fm/music/Rammstein"
            },
            "image": [
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/34s/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": "small"
                },
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/64s/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": "medium"
                },
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/174s/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": "large"
                },
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": "extralarge"
                },
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": "mega"
                },
                {
                    "#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
                    "size": ""
                }
            ]
        }
    ],
    "@attr": {
        "artist": "Rammstein"
    }
}
}

提前感谢您的回复。 附:堆栈中的第一个问题溢出...... yeeee!

3 个答案:

答案 0 :(得分:0)

看起来类似的轨道对象在结构上与trackMatches对象不同。

我建议为SimilarTrack响应创建第二个类对象。

SimilarTrack会有一个Artist对象和一个Streamable对象

TrackMatches将Artist作为字符串并可流式化为字符串

答案 1 :(得分:0)

继承可以在这里使用......

为常见对象制作一个通用类 -
我正在考虑我的榜样 -
比如说,每个回复都会有一个共同的价值 - 那就是"status":"success"

我将制作一个基类 -

BaseResponse.java

public class BaseResponse {

    @SerializedName("status")
    @Expose
    private String status;
}

我们可以扩展这个需要解析状态的类 -

public class ResponseOne extends BaseResponse {

    @SerializedName("name_one")
    @Expose
    private String nameOne;
}

public class ResponseOne extends BaseResponse {

    @SerializedName("name_two")
    @Expose
    private String nameTwo;
}

希望它有意义; - )

答案 2 :(得分:0)

解决方案是使用GSON的多态性功能。 This tutorial可能有所帮助。