Java Gson没有通过改造将JSON正确序列化到POJO中
我从纽约时报TopStories API返回了以下JSONJava 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",
{
"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);
}