Gson没有使用Retrofit

时间:2015-07-03 20:36:19

标签: java json gson retrofit

我从NYTimes 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,我不确定这是否对此有任何影响。

我正在使用Retrofit,并且在回调中永远无法访问我的onSuccess方法。我有这样的模型类:

主要模型类

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;
    }

}

你明白了,我有"multimedia"的另一个模型类,好了继续我创建了一个RestAdapter,如下所示:

private NYTimesService() {

    mAsyncRestAdapter = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    request.addEncodedQueryParam("api-key", API_KEY);
                }
            })
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();
}

我有一个像这样的API接口:

public interface ITopStories {

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

}

我的Callback<T>定义如下:

@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);
}

Log.d(TAG, "onLoadTopStories");被称为罚款,问题是永远无法达到Log.d(TAG, "onSuccess");。这是什么问题?

一些注释:

  • &#34;结果&#34;如果是空的
  • ,可以是数组或字符串
  • 同样的事情&#34; multimedia&#34;
  • 令我感到困惑的是.getCopyright()getStatus()从未在TopStories.java
  • 中序列化

同样RetrofitGET请求没有任何问题,它会正确启动它:

enter image description here

更新

onFailure添加了日志语句,我得到以下信息:

  

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_ARRAY,但在第1行第10819行为STRING路径$ .results [4] .multimedia

多媒体可以是数组或空字符串

"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"
            }
        ]

2 个答案:

答案 0 :(得分:2)

好的,我能够通过创建扩展Gson JsonDeserializer<T>类的自定义反序列化类来实现这一点。以下代码对我有用:

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");
    }
}
}

我将以下构造函数添加到Result.java

public Result(String title, Multimedia ... multimedia) {
    this.mTitle = title.replace("\"", "");;
    mMultimedia = Arrays.asList(multimedia);
}

我仍然觉得这有些笨拙,并且有一个更好的解决方案。我会对此进行更多调查,但目前这种情况正常。您可以向Multimedia构造函数添加更多参数,但这仍然不能完全满足我作为某种方式的答案。

这是我现在看到的结果:

enter image description here

该应用程序的源代码位于:NYTimes Android App Repo

答案 1 :(得分:0)

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