2017-01-21 25 views
1

のインタフェース持つシンプルなレトロフィット・インターフェースを使用してレトロフィットの戻り値の型を定義し代わりにクラス

interface Movies { 
    @GET("movies/trending") 
    fun trending(): Observable<List<TrendingMovie>> 
} 

それは(このインタフェースを実装する匿名クラスのの観察可能emititngリストになり結果)インタフェースとしてTrendingMovieを定義することは可能ですか?

(私はこれを行うのですか試してみましたが、私はjava.lang.IllegalArgumentExceptionが得た:インタフェースcom.test.TrendingMovieのためノーJsonAdapter)を

答えて

1

はい、それは間違いなく可能ですが、用のカスタムデシリアライザを追加する必要がありますインタフェース。これは、使用するデシリアライズツール用のカスタムタイプのデシリアライザを登録することで行います。

ジャクソン(これは結局コトリンクラスでの作業に使用することをお勧めします)はObjectMapperModuleを追加して行います。ここで私はjackson-module-kotlinでこれを行うために作られた手順です。あなたのインターフェイスのために追加

  1. JsonDeserializerでカスタムModuleを作成します。

    fun trendingMovieModule(): Module = SimpleModule().apply { 
        val deserializer: JsonDeserializer<TrendingMovie> = object : JsonDeserializer<TrendingMovie>() { 
         override fun deserialize(p: JsonParser, ctxt: DeserializationContext): TrendingMovie { 
          val node = p.codec.readTree<JsonNode>(p) 
    
          return object : TrendingMovie { // Your anonymous class here, for example: 
           val name = node["movie"]["title"] 
           val watchers = node["watchers"].intValue() 
    
           override fun toString(): String = "$name, watchers: $watchers" 
          } 
         } 
        } 
    
        addDeserializer(TrendingMovie::class.java, deserializer) 
    } 
    
  2. あなたがRetrofitに使用ObjectMapperでモジュールを登録ビルダー:

    val mapper = jacksonObjectMapper() 
         .registerModule(trendingMovieModule()) 
    
  3. 0123にはmapperを使用しますビルダー:

    val r = Retrofit.Builder() 
         // other necessary configuration omitted, e.g. custom OkHttpClient 
         .baseUrl("https://api.trakt.tv") 
         .addConverterFactory(JacksonConverterFactory.create(mapper)) 
         .build().create(Movies::class.java) 
    

    JacksonConverterFactoryは、依存関係が必要です。converter-jackson

  4. 完了!今では動作するはずです:

    r.trending().flatMap { Observable.from(it) }.forEach(::println) 
    

    完全なソース・ファイル:(here)

関連する問題