2017-07-21 15 views
0

ジャクソンを使用してscalaにkafka jsonデシリアライザを作成していますが、jacksonのreadValue()メソッドにジェネリックタイプのクラスを提供することに問題があります。たとえば:Scala classOfカフカjsonデシリアライザのジェネリックタイプ

... 
import org.apache.kafka.common.serialization.Deserializer 

class JsonDeserializer[T] extends Deserializer[Option[T]] { 

    val mapper = (new ObjectMapper() with ScalaObjectMapper) 
    .registerModule(DefaultScalaModule) 
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 
    .registerModule(new JavaTimeModule()) 
    .findAndRegisterModules() 
    .asInstanceOf[ObjectMapper with ScalaObjectMapper] 

    def deserialize(topic: String, bytes: Array[Byte]): Option[T] = { 
    Option(bytes) match { 
     case Some(b) => Some(mapper.readValue(bytes, classOf[T])) 
     case None => None 
    } 

    } 

    def configure(configs: java.util.Map[String, _], isKey: Boolean) {} 
    def close(): Unit = {} 
} 

deserialize方法でmapper.readValue(bytes, classOf[T])に注目してください。コンパイルに失敗しましたが、 "クラスタイプが必要ですがTが見つかりました"。

どうすればいいですか?

答えて

0

Javaの汎用型は実行時に消去されるため、明示的に渡さずにClassを回復する方法はありません。

Javaについては明らかです。 (implicit ct: ClassTag[T])または略語[T: ClassTag]を使用して、建設時にClassTagを(暗黙的に)取得すると、後でClassを取得できます。

import scala.reflect._ 

class JsonDeserializer[T: ClassTag] extends Deserializer[Option[T]] { 
    ... 
    mapper.readValue(bytes, classTag[T].runtimeClass.asInstanceOf[Class[T]]) 
+0

私は実際にはなく、 'バインドコンテキストことを試してみました[T:ClassTag]:*クラスcom.meをインスタンス化できませんでした'により自動的にそれをインスタンス化カフカができなくなり、プライマリコンストラクタの引数なしの署名を変更するようです.serialization.JsonDeserializer publicで引数のないコンストラクタはありますか?* – novon

+0

@novon残念ながら、それは不可能です。特定のタイプの 'Foo'では、' OptFooDeserializer extends JsonDeserializer [Foo] 'クラスを簡単に作成し、' OptFooDeserializer'を使うことができます。 – ephemient

+0

それは感謝します、ありがとう。 – novon

関連する問題