2015-07-03 75 views
2

我有以下JSON从NYTimes TopStories API返回;Gson没有正确序列化JSON到POJO与改造

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

纽约时报返回此JSONtext/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");永远达不到。这里有什么问题?

一些注意事项:

  • “结果”可以是一个数组或一个字符串,如果其空
  • 以“多媒体”
  • 同样的事情是什么令我感到困惑的是,.getCopyright()getStatus()不被序列化到首先在TopStories.java

而且Retrofit具有与GET请求,并将其初始没有问题TES得当:

enter image description here

更新

添加日志报表onFailure,我得到以下几点:

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException :预计BEGIN_ARRAY,但在第1行10819路径$ .results [4]的STRING。多媒体

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

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

也许失败叫什么名字? –

+0

哦,是的,我忘了在onFailure中包含Log语句,更新了问题。 – AndyRoid

+0

不知道为什么有人反对,这是一个合法的问题。 – AndyRoid

回答

2

好我能够通过创建一个自定义的反序列化类来扩展GsonJsonDeserializer<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

0

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

+0

错误如果您阅读“多媒体”作为数组或字符串返回的问题。 – AndyRoid

+0

嗯,我写的立场,阅读错误。它期望在json中读取一个数组,但它会得到一个String –

+0

是的,这非常明显,现在我正在为此编写一个解决方案。 – AndyRoid