2017-02-25 1 views
0

何らかの理由で、POJOに変換できません。私が作って試した呼び出しは次のようなものです:エラーのためjson文字列をPOJOに変換できません。文字列が必要ですが、BEGIN_ARRAYでした。

NewsEntities newsEntities = new Gson().fromJson(jsonString, NewsEntities.class); 

jsonが配列にないという謎です。そのjsonObject私は思う。 jsonStringは私がアンドロイドに入るエラーがあるhere

です:

Caused by: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 1006 path $.results[0].org_facet 
02-24 23:42:49.955 15463-15531/news.myapp.com.technewssample W/System.err:  at com.google.gson.stream.JsonReader.nextString(JsonReader.java:831) 
02-24 23:42:49.955 15463-15531/news.myapp.com.technewssample W/System.err:  at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:422) 
02-24 23:42:49.955 15463-15531/news.myapp.com.technewssample W/System.err:  at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:410) 
02-24 23:42:49.955 15463-15531/news.myapp.com.technewssample W/System.err:  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116) 
02-24 23:42:49.956 15463-15531/news.myapp.com.technewssample W/System.err:  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(Reflect 

newsEntitiesクラス自体は次のようになり、私は単にhttp://www.jsonschema2pojo.org/からそれを作った:

public class NewsEntities implements Parcelable 
{ 

    @SerializedName("status") 
    @Expose 
    private String status; 
    @SerializedName("copyright") 
    @Expose 
    private String copyright; 
    @SerializedName("section") 
    @Expose 
    private String section; 
    @SerializedName("last_updated") 
    @Expose 
    private String lastUpdated; 
    @SerializedName("num_results") 
    @Expose 
    private Integer numResults; 
    @SerializedName("results") 
    @Expose 
    private List<Result> results = null; 
    public final static Parcelable.Creator<NewsEntities> CREATOR = new Creator<NewsEntities>() { 


     @SuppressWarnings({ 
      "unchecked" 
     }) 
     public NewsEntities createFromParcel(Parcel in) { 
      NewsEntities instance = new NewsEntities(); 
      instance.status = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.copyright = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.section = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.lastUpdated = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.numResults = ((Integer) in.readValue((Integer.class.getClassLoader()))); 
      in.readList(instance.results, (Result.class.getClassLoader())); 
      return instance; 
     } 

     public NewsEntities[] newArray(int size) { 
      return (new NewsEntities[size]); 
     } 

    } 
    ; 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    public String getCopyright() { 
     return copyright; 
    } 

    public void setCopyright(String copyright) { 
     this.copyright = copyright; 
    } 

    public String getSection() { 
     return section; 
    } 

    public void setSection(String section) { 
     this.section = section; 
    } 

    public String getLastUpdated() { 
     return lastUpdated; 
    } 

    public void setLastUpdated(String lastUpdated) { 
     this.lastUpdated = lastUpdated; 
    } 

    public Integer getNumResults() { 
     return numResults; 
    } 

    public void setNumResults(Integer numResults) { 
     this.numResults = numResults; 
    } 

    public List<Result> getResults() { 
     return results; 
    } 

    public void setResults(List<Result> results) { 
     this.results = results; 
    } 

    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeValue(status); 
     dest.writeValue(copyright); 
     dest.writeValue(section); 
     dest.writeValue(lastUpdated); 
     dest.writeValue(numResults); 
     dest.writeList(results); 
    } 

    public int describeContents() { 
     return 0; 
    } 

    } 

UPDATE:結果のクラスはこちら

public class Result implements Parcelable 
{ 

    @SerializedName("section") 
    @Expose 
    private String section; 
    @SerializedName("subsection") 
    @Expose 
    private String subsection; 
    @SerializedName("title") 
    @Expose 
    private String title; 
    @SerializedName("abstract") 
    @Expose 
    private String _abstract; 
    @SerializedName("url") 
    @Expose 
    private String url; 
    @SerializedName("byline") 
    @Expose 
    private String byline; 
    @SerializedName("item_type") 
    @Expose 
    private String itemType; 
    @SerializedName("updated_date") 
    @Expose 
    private String updatedDate; 
    @SerializedName("created_date") 
    @Expose 
    private String createdDate; 
    @SerializedName("published_date") 
    @Expose 
    private String publishedDate; 
    @SerializedName("material_type_facet") 
    @Expose 
    private String materialTypeFacet; 
    @SerializedName("kicker") 
    @Expose 
    private String kicker; 
    @SerializedName("des_facet") 
    @Expose 
    private List<String> desFacet = null; 
    @SerializedName("org_facet") 
    @Expose 
    private String orgFacet; 
    @SerializedName("per_facet") 
    @Expose 
    private String perFacet; 
    @SerializedName("geo_facet") 
    @Expose 
    private List<String> geoFacet = null; 
    @SerializedName("multimedia") 
    @Expose 
    private List<Multimedium> multimedia = null; 
    public final static Parcelable.Creator<Result> CREATOR = new Creator<Result>() { 


     @SuppressWarnings({ 
      "unchecked" 
     }) 
     public Result createFromParcel(Parcel in) { 
      Result instance = new Result(); 
      instance.section = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.subsection = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.title = ((String) in.readValue((String.class.getClassLoader()))); 
      instance._abstract = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.url = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.byline = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.itemType = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.updatedDate = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.createdDate = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.publishedDate = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.materialTypeFacet = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.kicker = ((String) in.readValue((String.class.getClassLoader()))); 
      in.readList(instance.desFacet, (java.lang.String.class.getClassLoader())); 
      instance.orgFacet = ((String) in.readValue((String.class.getClassLoader()))); 
      instance.perFacet = ((String) in.readValue((String.class.getClassLoader()))); 
      in.readList(instance.geoFacet, (java.lang.String.class.getClassLoader())); 
      in.readList(instance.multimedia, (Multimedium.class.getClassLoader())); 
      return instance; 
     } 

     public Result[] newArray(int size) { 
      return (new Result[size]); 
     } 

    } 
    ; 

    public String getSection() { 
     return section; 
    } 

    public void setSection(String section) { 
     this.section = section; 
    } 

    public String getSubsection() { 
     return subsection; 
    } 

    public void setSubsection(String subsection) { 
     this.subsection = subsection; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getAbstract() { 
     return _abstract; 
    } 

    public void setAbstract(String _abstract) { 
     this._abstract = _abstract; 
    } 

    public String getUrl() { 
     return url; 
    } 

    public void setUrl(String url) { 
     this.url = url; 
    } 

    public String getByline() { 
     return byline; 
    } 

    public void setByline(String byline) { 
     this.byline = byline; 
    } 

    public String getItemType() { 
     return itemType; 
    } 

    public void setItemType(String itemType) { 
     this.itemType = itemType; 
    } 

    public String getUpdatedDate() { 
     return updatedDate; 
    } 

    public void setUpdatedDate(String updatedDate) { 
     this.updatedDate = updatedDate; 
    } 

    public String getCreatedDate() { 
     return createdDate; 
    } 

    public void setCreatedDate(String createdDate) { 
     this.createdDate = createdDate; 
    } 

    public String getPublishedDate() { 
     return publishedDate; 
    } 

    public void setPublishedDate(String publishedDate) { 
     this.publishedDate = publishedDate; 
    } 

    public String getMaterialTypeFacet() { 
     return materialTypeFacet; 
    } 

    public void setMaterialTypeFacet(String materialTypeFacet) { 
     this.materialTypeFacet = materialTypeFacet; 
    } 

    public String getKicker() { 
     return kicker; 
    } 

    public void setKicker(String kicker) { 
     this.kicker = kicker; 
    } 

    public List<String> getDesFacet() { 
     return desFacet; 
    } 

    public void setDesFacet(List<String> desFacet) { 
     this.desFacet = desFacet; 
    } 

    public String getOrgFacet() { 
     return orgFacet; 
    } 

    public void setOrgFacet(String orgFacet) { 
     this.orgFacet = orgFacet; 
    } 

    public String getPerFacet() { 
     return perFacet; 
    } 

    public void setPerFacet(String perFacet) { 
     this.perFacet = perFacet; 
    } 

    public List<String> getGeoFacet() { 
     return geoFacet; 
    } 

    public void setGeoFacet(List<String> geoFacet) { 
     this.geoFacet = geoFacet; 
    } 

    public List<Multimedium> getMultimedia() { 
     return multimedia; 
    } 

    public void setMultimedia(List<Multimedium> multimedia) { 
     this.multimedia = multimedia; 
    } 

    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeValue(section); 
     dest.writeValue(subsection); 
     dest.writeValue(title); 
     dest.writeValue(_abstract); 
     dest.writeValue(url); 
     dest.writeValue(byline); 
     dest.writeValue(itemType); 
     dest.writeValue(updatedDate); 
     dest.writeValue(createdDate); 
     dest.writeValue(publishedDate); 
     dest.writeValue(materialTypeFacet); 
     dest.writeValue(kicker); 
     dest.writeList(desFacet); 
     dest.writeValue(orgFacet); 
     dest.writeValue(perFacet); 
     dest.writeList(geoFacet); 
     dest.writeList(multimedia); 
    } 

    public int describeContents() { 
     return 0; 
    } 

} 

答えて

1

自動POJOジェネレータは、特にマッピングされたフィールドが多態的である場合、または何らかの理由で非標準的な手法を使用する場合、誤ったマッピングを生成することがあります。あなたが得ているエラーによると、マッピングにはStringが必要ですが、JSONにはその場所に配列があります。あなたのケースでは、$.results[0].org_facetポイントに:あなたはString orgFacetList<String> orgFacetへのマッピングを変更した場合は

...,"org_facet":["Amazon.com Inc","Cravath Swaine \u0026 Moore"],... 
      // ^____here 

、あなたがperFacetmultimediaのような他の分野のための同様のエラーを取得します(いくつかのより多くの周りがあります)。これらのフィールドはリストのためのものであり、またはnullの空の配列のマーカにすぎないため、Gsonはそのようなメッセージフォーマットのためにそれ自体を処理することはできません。ただし、単一のGsonインスタンスを使用して逆シリアル化されたすべてのリストに適用可能なカスタムタイプのアダプタを作成するこのようなフィールドでも動作させることができます。それが使われている方法

final class ArrayOrEmptyStringTypeAdapterFactory 
     implements TypeAdapterFactory { 

    private static final TypeAdapterFactory arrayOrEmptyStringTypeAdapterFactory = new ArrayOrEmptyStringTypeAdapterFactory(); 

    private ArrayOrEmptyStringTypeAdapterFactory() { 
    } 

    static TypeAdapterFactory getArrayOrEmptyStringTypeAdapterFactory() { 
     return arrayOrEmptyStringTypeAdapterFactory; 
    } 

    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) { 
     if (List.class.isAssignableFrom(typeToken.getRawType())) { // Is it an instance of java.util.List? Not that getRawType() and getType() have different purposes 
      final TypeAdapter<List<Object>> typeAdapter = getArrayOrEmptyStringTypeAdapter(gson, getListElementType(typeToken.getType())); 
      @SuppressWarnings("unchecked") 
      final TypeAdapter<T> castTypeAdapter = (TypeAdapter<T>) typeAdapter; 
      return castTypeAdapter; 
     } 
     return null; 
    } 

    private static Type getListElementType(final Type type) { 
     return type instanceof ParameterizedType // Is it a generic type with type parameters? 
       ? ((ParameterizedType) type).getActualTypeArguments()[0] // If yes, then we know that java.util.List has one type paremeter only 
       : Object.class; // Otherwise it's a raw list, and no element type info is provided 
    } 

} 

final class ArrayOrEmptyStringTypeAdapter<E> 
     extends TypeAdapter<List<E>> { 

    private final Gson gson; 
    private final Type elementType; 

    private ArrayOrEmptyStringTypeAdapter(final Gson gson, final Type elementType) { 
     this.gson = gson; 
     this.elementType = elementType; 
    } 

    static <E> TypeAdapter<List<E>> getArrayOrEmptyStringTypeAdapter(final Gson gson, final Type elementType) { 
     return new ArrayOrEmptyStringTypeAdapter<>(gson, elementType); 
    } 

    @Override 
    public void write(final JsonWriter out, final List<E> list) { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public List<E> read(final JsonReader in) 
      throws IOException { 
     final JsonToken token = in.peek(); // Peek the next token 
     switch (token) { 
     case BEGIN_ARRAY: // If it's an array begin `[`, then parse it as an array 
      return parseAsArray(in); 
     case STRING: // Or if it's a string, parse it in another way 
      return parseAsString(in); 
     default: 
      throw new MalformedJsonException("Unexpected token: " + token); 
     } 
    } 

    private List<E> parseAsArray(final JsonReader in) 
      throws IOException { 
     final List<E> list = new ArrayList<>(); 
     in.beginArray(); // Consume `[` from the token stream 
     while (in.peek() != END_ARRAY) { 
      final E element = gson.fromJson(in, elementType); // Delegate downstream parsing to the Gson instance 
      list.add(element); 
     } 
     in.endArray(); // Consume `]` from the token stream 
     return list; 
    } 

    private List<E> parseAsString(final JsonReader in) 
      throws IOException { 
     in.skipValue(); // in.nextString() consumes more memory accumulating the result 
     return new ArrayList<>(); // Or null -- up to you. Or even Collections.emptyList(), but Gson uses mutable lists so we do 
    } 

} 

次のことは、型アダプタ工場を経由してタイプのアダプタとGsonインスタンスを結合さ

private static final Gson gson = new GsonBuilder() 
     .registerTypeAdapterFactory(getArrayOrEmptyStringTypeAdapterFactory()) 
     .create(); 
final NewsEntities newEntities = gson.fromJson(jsonString, NewsEntities.class); 
System.out.println(newEntities.results.get(0).orgFacet); 
System.out.println(newEntities.results.get(0).perFacet) 

出力:

[Amazon.com社、Cravathスウェイン&ムーア]
[Bezos氏、ジェフリー・P]

1

結果クラスを添付していませんが、結果クラスにorg_facetの配列ではなく文字列フィールドがあるように見えます。しかし、Resultクラスを追加すると答えが簡単になります。

+0

私はあなたの診断結果クラスを掲載。 – j2emanue

関連する問題