2016-05-16 9 views
0

私はplayフレームワークで新しく、カフェカトピックに挿入するためにいくつかの製品についてアマゾンに定期的に質問したいと思っています。コードをコンパイルしてみてください。Play Framework 2.xでFutureオブジェクトの暗黙のJScript Writesを実装する方法

これはKafkaProducerのコードです:

ファイルexample.model.AmazonProducerExample

//ユーザーからの提案で更新方法は、君たちに感謝します!

package example.utils 

import jodd.lagarto.dom.{NodeSelector, LagartoDOMBuilder} 
import example.model.AmazonProduct 
import scala.collection.JavaConversions._ 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 

import play.api.libs.json._ 
import example.utils._ 
import example.producer._ 

object AmazonPageParser { 

private val topicName = "amazonRatingsTopic" 

private val producer = Producer[String](topicName) 


def parse(productId: String): Future[AmazonProduct] = { 

val url = s"http://www.amazon.com/dp/$productId" 
HttpClient.fetchUrl(url) map { 
    httpResponse => 
    if (httpResponse.getStatusCode == 200) { 
     val body = httpResponse.getResponseBody 
     val domBuilder = new LagartoDOMBuilder() 
     val doc = domBuilder.parse(body) 

     val responseUrl = httpResponse.getUri.toString 
     val nodeSelector = new NodeSelector(doc) 
     val title = nodeSelector.select("span#productTitle").head.getTextContent 
     val img = nodeSelector.select("div#main-image-container img").head.getAttribute("src") 
     val description = nodeSelector.select("div#feature-bullets").headOption.map(_.getHtml).mkString 

     val amazonProduct = AmazonProduct(productId, title, responseUrl, img, description) 

     println("amazonProduct is " + amazonProduct.toString) 
     amazonProduct 
    } else { 
     println("An error happened!") 
     throw new RuntimeException(s"Invalid url $url") 
    } 
}//map 
}//parse method 

def main(args: Array[String]): Unit = { 

//Scala Puzzlers... 
AmazonPageParser.parse("0981531679").onSuccess { case amazonProduct => 

    implicit val amazonFormat = Json.format[AmazonProduct] 
    producer.send(Json.toJson(amazonProduct).toString) 
    println("amazon product sent to kafka cluster..." + amazonProduct.toString) 
} 
} 
} 

ファイルexample.model.Models

package example.model 

import play.api.libs.json.Json 
import reactivemongo.bson.Macros 

case class AmazonProduct(itemId: String, title: String, url: String, img: String, description: String) 
case class AmazonRating(userId: String, productId: String, rating: Double) 

case class AmazonProductAndRating(product: AmazonProduct, rating: AmazonRating) 

// For MongoDB 
object AmazonRating { 
implicit val amazonRatingHandler = Macros.handler[AmazonRating] 
implicit val amazonRatingFormat = Json.format[AmazonRating] 
} 

ファイルexample.utils.AmazonPageParser

コンパイラ私は、このエラーを返します:

[error] /Users/aironman/my-recommendation-spark-engine/src/main/scala/example/producer/AmazonProducerExample.scala:25: No Json serializer found for type scala.concurrent.Future[example.model.AmazonProduct]. Try to implement an implicit Writes or Format for this type. 
[error]  producer.send(Json.toJson(amazonProduct).toString) 
[error]       ^

私はこのpost with most votesをreadedしているが、それは私にとってはうまくいかない。

誰かが私を助けることができますか?

+1

'Future [T]'の場合は 'Writes [T]'を使用し、 'future 'の内部にwrite opsを呼び出します – cchantep

+0

こんにちは。私が理解しているように、あなたはkafkaトピックへの書き込み操作をAmazonPageParser.parseメソッドの中に入れることを指しているのですか?しかし、私は分離された方法でこの機能を持っていたいと思います... – aironman

+0

将来は完了したので、 'map'、' flatMap'や値の適切な演算子を使って書いてください。私のための「未来」を理解するための一般的な質問。 – cchantep

答えて

2

Writes[T]は、Jsonを生成する。あなたはブロックせずに直接Futureからそれを生成することはできません。

amazonPageParser.parse(productId).onSuccess { case amazonProduct => 
    producer.send(Json.toJson(amazonProduct).toString) 
} 

またはその他の未来の方法では、mapforeachのように:あなたはこのように、この未来への「コールバック」を追加することができますしかし

+0

ありがとうございます@タイと嘆き。私は解決策でスレッドを更新します – aironman

関連する問題