Java Gson没有通过改造将JSON正确序列化到POJO中

Java Gson没有通过改造将JSON正确序列化到POJO中,java,json,gson,retrofit,Java,Json,Gson,Retrofit,我从纽约时报TopStories API返回了以下JSON { "status": "OK", "copyright": "Copyright (c) 2015 The New York Times Company. All Rights Reserved.", "last_updated": "2015-07-03T01:25:02-05:00", "num_results": 21, "results": [ { "section": "World",

我从纽约时报TopStories API返回了以下JSON

{
"status": "OK",
"copyright": "Copyright (c) 2015 The New York Times Company. All Rights Reserved.",
"last_updated": "2015-07-03T01:25:02-05:00",
"num_results": 21,
"results": [
    {
        "section": "World",
        "subsection": "Africa",
        "title": "Tunisia Jihadist Died in Libya Strike, U.S. Official Says",
        "abstract": "Seifallah Ben Hassine, one of Osama bin Laden’s top lieutenants and Tunisia’s most wanted jihadist, was killed in an American airstrike in Libya last month, a senior United States official said.",
        "url": "http://www.nytimes.com/2015/07/03/world/africa/jihadist-from-tunisia-died-in-strike-in-libya-us-official-says.html",
        "byline": "By CARLOTTA GALL and ERIC SCHMITT",
        "item_type": "Article",
        "updated_date": "2015-07-02T21:18:07-5:00",
        "created_date": "2015-07-02T21:18:10-5:00",
        "published_date": "2015-07-03T04:00:00-5:00",
        "material_type_facet": "News",
        "kicker": "",
        "des_facet": [
            "Terrorism",
            "Defense and Military Forces"
        ],
        "org_facet": "",
        "per_facet": [
            "Hassine, Seifallah Ben",
            "bin Laden, Osama"
        ],
        "geo_facet": [
            "Tunisia",
            "Libya"
        ],
        "multimedia": ""
    }
]
}
NYTimes返回此
JSON
,其标题为
text/JSON
,我不确定这是否有任何影响

我正在使用改型,而我的onSuccess方法在回调中从未达到。我将模型类声明为:

@Subscribe
public void onLoadTopStories(LoadTopStories loadTopStories) {
    Log.d(TAG, "onLoadTopStories");
    Callback<TopStories> callback = new Callback<TopStories>() {
        @Override
        public void success(TopStories topStories, Response response) {
            Log.d(TAG, "onSuccess");
            mBus.post(new LoadedTopStories(topStories));
        }

        @Override
        public void failure(RetrofitError error) {

        }
    };
    sClient.getTopStories(callback);
}
主要车型类别

public class TopStories {

    @SerializedName("status")
    private String mStatus;
    public String getStatus() {
        return mStatus;
    }

    @SerializedName("copyright")
    private String mCopyright;
    public String getCopyright() {
        return mCopyright;
    }

    @SerializedName("last_updated")
    private String mLastUpdated;
    public String getLastUpdated() {
        return mLastUpdated;
    }

    @SerializedName("num_results")
    private int mNumResults;
    public int getNumResults() {
        return mNumResults;
    }

    @SerializedName("results")
    private List<Result> mResults;
    public List<Result> getResults() {
        return mResults;
    }

}
public class Result {

    @SerializedName("section")
    private String mSection;
    public String getSection() {
        return mSection;
    }

    @SerializedName("subsection")
    private String mSubSection;
    public String getSubSection() {
        return mSubSection;
    }

    @SerializedName("title")
    private String mTitle;
    public String getTitle() {
        return mTitle;
    }

    @SerializedName("abstract")
    private String mAbstract;
    public String getAbstract() {
        return mAbstract;
    }

    @SerializedName("url")
    private String mUrl;
    public String getUrl() {
        return mUrl;
    }

    @SerializedName("byline")
    private String myByLine;
    public String getMyByLine() {
        return myByLine;
    }

    @SerializedName("item_type")
    private String mItemType;
    public String getItemType() {
        return mItemType;
    }

    @SerializedName("updated_date")
    private String mUpdatedDate;
    public String getUpdatedDate() {
        return mUpdatedDate;
    }

    @SerializedName("created_date")
    private String mCreatedDate;
    public String getCreatedDate() {
        return mCreatedDate;
    }

    @SerializedName("multimedia")
    private List<Multimedia> mMultimedia;
    public List<Multimedia> getMultimedia() {
        return mMultimedia;
    }

}
我有这样一个API接口:

public interface ITopStories {

    @Headers("Content-Type: text/json")
    @GET("/topstories/v1/home.json")
    void getTopStories(Callback<TopStories> callback);

}

您的POJO不正确,多媒体不是列表,它只是一个字符串,根据您的JSON

好的,我可以通过创建一个自定义反序列化类来实现这一点,该类扩展了
Gson
JsonDeserializer
类。以下代码适用于我:

public class ResultsDeserializerJson implements JsonDeserializer<Result> {

@Override
public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

    JsonElement titleElement = json.getAsJsonObject().get("title");
    JsonElement multimediaElement = json.getAsJsonObject().get("multimedia");
    if (multimediaElement.isJsonArray()) {
        return new Result(
                titleElement.toString(),
                (Multimedia[]) context.deserialize(multimediaElement.getAsJsonArray(), Multimedia[].class));
    } else if (multimediaElement.getAsString().equals("")) {
        Multimedia multimedia = new Multimedia();
        multimedia.setFormat("");
        multimedia.setUrl("");
        return new Result(titleElement.toString(), multimedia);
    } else {
        Log.d("ResultsDeserializerJson", multimediaElement.toString());
        throw new JsonParseException("Unsupported type of multimedia element");
    }
}
}
我仍然觉得这有点老套,有一个更好的解决方案。我将对此进行更多的调查,但目前效果良好。您可以向
多媒体
构造函数添加更多参数,但这在某些方面仍然不能完全满足我的要求

这就是我现在看到的结果:


应用程序的源代码如下:

可能调用了失败?哦,是的,我忘了在onFailure,updated question中包含日志语句。不确定为什么有人否决了这个问题,这是一个合法的问题。如果您阅读问题“multimedia”返回数组或字符串,则会出错。我写的内容正确,请阅读错误。它期望用json读取一个数组,但它得到了一个StringYes,这是非常明显的,我现在正在为此编写一个解决方案。
"multimedia": [
            {
                "url": "http://static01.nyt.com/images/2015/07/04/world/04Greece1-web/04Greece1-web-thumbStandard.jpg",
                "format": "Standard Thumbnail",
                "height": 75,
                "width": 75,
                "type": "image",
                "subtype": "photo",
                "caption": "A Greek Orthodox priest giving money to a man on a street in Thessaloniki, Greece, on Friday.",
                "copyright": "Giannis Papanikos/Associated Press"
            },
            {
                "url": "http://static01.nyt.com/images/2015/07/04/world/04Greece1-web/04Greece1-web-thumbLarge.jpg",
                "format": "thumbLarge",
                "height": 150,
                "width": 150,
                "type": "image",
                "subtype": "photo",
                "caption": "A Greek Orthodox priest giving money to a man on a street in Thessaloniki, Greece, on Friday.",
                "copyright": "Giannis Papanikos/Associated Press"
            },
            {
                "url": "http://static01.nyt.com/images/2015/07/04/world/04Greece1-web/04Greece1-web-articleInline.jpg",
                "format": "Normal",
                "height": 127,
                "width": 190,
                "type": "image",
                "subtype": "photo",
                "caption": "A Greek Orthodox priest giving money to a man on a street in Thessaloniki, Greece, on Friday.",
                "copyright": "Giannis Papanikos/Associated Press"
            },
            {
                "url": "http://static01.nyt.com/images/2015/07/04/world/04Greece1-web/04Greece1-web-mediumThreeByTwo210.jpg",
                "format": "mediumThreeByTwo210",
                "height": 140,
                "width": 210,
                "type": "image",
                "subtype": "photo",
                "caption": "A Greek Orthodox priest giving money to a man on a street in Thessaloniki, Greece, on Friday.",
                "copyright": "Giannis Papanikos/Associated Press"
            }
        ]
public class ResultsDeserializerJson implements JsonDeserializer<Result> {

@Override
public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

    JsonElement titleElement = json.getAsJsonObject().get("title");
    JsonElement multimediaElement = json.getAsJsonObject().get("multimedia");
    if (multimediaElement.isJsonArray()) {
        return new Result(
                titleElement.toString(),
                (Multimedia[]) context.deserialize(multimediaElement.getAsJsonArray(), Multimedia[].class));
    } else if (multimediaElement.getAsString().equals("")) {
        Multimedia multimedia = new Multimedia();
        multimedia.setFormat("");
        multimedia.setUrl("");
        return new Result(titleElement.toString(), multimedia);
    } else {
        Log.d("ResultsDeserializerJson", multimediaElement.toString());
        throw new JsonParseException("Unsupported type of multimedia element");
    }
}
}
public Result(String title, Multimedia ... multimedia) {
    this.mTitle = title.replace("\"", "");;
    mMultimedia = Arrays.asList(multimedia);
}