2017-02-12 2 views
0

Retrofitネットワークコールの応答をActiveAndroidでキャッシュします。Gson、Retrofit、Active AndroidでネストされたJSONオブジェクトをStringとしてデシリアライズする方法

私は次のようになり、クラス作っ: -

class Article extends Model { 
    @Column(name = "title") 
    @SerializedName("title") 
    @Expose 
    public String title; 

    @Column(name = "authors") 
    @SerializedName("authors") 
    @Expose 
    private String authors; 
} 

対応するJSONのようなものである: - 正気の方法はAuthorArticleの間にあり、多くの関係を用いることであろう

{ 
    "title":"Some title", 
    "authors": [{ 
    "name": "Name", 
    "twitter":"@whatever" 
    }] 
} 

をしかし、著者は@Exposeアノテーション(または変数)をArticleクラスに持たないため、データベースに保存されていません。多くの呼び出しがメソッドになるため、そのアノテーションを持つ方法はありませんここではList<Author>を返します。

// This will not work 
@Expose 
public List<Author> authors() { 
    return getMany(Author.class, "Article"); 
} 

私は、JSONオブジェクトをデータベースに格納して文字列として格納し、アクセスをシリアル化/デシリアライズすることを考えました。

これは、authors変数をList<Author>クラスにして、type serializerを提供する必要があります。

このアプローチの問題は、データベースに保存されている汎用タイプを知る方法がないことです。私はList<Author>型を返すことはできません。作家のように、JSON全体にいくつかのJSON配列があるからです。

私が考えた最終的な解決策は、文字列として格納し、文字列として扱い、アクセスのためにデシリアライズするメソッドを作ることです。

private List<Author> _authors; 
public List<Author> authors() { 
    if (_authors == null) { 
     Gson gson = ServiceGenerator.gsonBuilder.create(); 
     Type type = new TypeToken<List<Author>>(){}.getType(); 
     _authors = gson.fromJson(authors, type); 
    } 

    return _authors; 
} 

しかし、私はこれを行うにしようとすると、GSONがエラーをスローします - - :このような

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY

は基本的に私は、文字列としてJSON配列を扱うしようとしていますと言って。

私の質問は、いくつかのJSON配列をGSONコンバータの文字列として扱う方法です。私が使用しています

私のレトロフィットBuilderは次のとおりです。 - 外観を取るための

public static final GsonBuilder gsonBuilder = new GsonBuilder() 
      .setDateFormat("yyyy-MM-dd'T'HH:mm:ss") 
      .excludeFieldsWithoutExposeAnnotation(); 

private static final Retrofit.Builder builder = new Retrofit.Builder() 
     .baseUrl(API_BASE_URL) 
     .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create())); 

ありがとう!

+0

あなたが何を意味するか、次のようにJsonObjectにLinkedTreeMapを変換してみLinkedTreeMap

  • としてそれをデシリアライズします*このアノテーションを持つ方法はありません。なぜなら、多くの呼び出しがメソッド呼び出しであるからです。リスト *? – Blackbelt

  • +0

    @Blackbeltが私の質問を更新して説明しました。 – Shobhit

    +0

    私はまだあなたがどういう意味を持っているのか分かりません。なぜ記事が '私的リスト著者;を保持できないのですか? – Blackbelt

    答えて

    0

    あなたは記事

    public class ArticleDeserializer implements JsonDeserializer<Article> { 
    
    
        @Override 
        public Article deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) 
         throws JsonParseException { 
    
        Article article = context.deserialize(json, Article.class); 
        JsonArray authors = json.getAsJsonObject().getAsJsonArray("authors"); 
        // convert authors as string and set it to artile 
        return article; 
    } 
    

    に登録され、それのためJsonDeserializerを使用することができますし、あなたはそれが文字列として格納するために黒帯が言っ

    gsonBuilder.registerTypeHierarchyAdapter(Article.class, new ArticleDeseriazer()) 
    
    0

    を、gsonするために登録する必要があります。

    これを行うには、Authorクラスと1:nクラスが必要です。私が理解する限り、関連性のデータを書き込むことは手動で行われるため、Articleを保存するときに関係を自分で保存する必要があります。ですから、ArticleクラスのAuthorクラス

    @Table(name = "Authors") 
    public class Author extends Model { 
        @Column(name = "Name") 
        public String name; 
        @Column(name = "Twitter") 
        public String twitter; 
    } 
    

    とフィールド

    private List<Author> authors; 
    

    を持っていると仮定すると、あなたはsave the authors like this

    article.save(); 
    for (author: Author in arcticle.authors) { 
        author.article = article; 
        author.save(); 
    } 
    

    、その後、あなたはArticleにアクセスするためのメソッドを追加することができます筆者の文書化:

    public List<Author> getAuthors() { 
        return getMany(Author.class, "Author"); 
    } 
    

    GSONはAuthorsを自分のテーブルに保存するときauthorsをフィールドauthorsに保存し、getAuthors()はデータベースから読み取ります。

    注:M:NおそらくActiveAndroidによって支持さjunction table, as described in this issue on github

    0

    一つの可能​​な解決策を必要としていないArticleAuthorとの関係、より理にかなっています。

    1. ちょうどオブジェクトとしてフィールドを宣言し、その後、Gsonは

      LinkedTreeMap<?,?> yourMap = ...; JsonObject jsonObject = gson.toJsonTree(yourMap).getAsJsonObject();

    関連する問題