如何在Play Framework 2.x中实现对未来对象的隐式Json写入
我是play framework的新手,我想定期向amazon询问一些产品,以便将它们插入到kafka主题中,当我尝试编译代码时会发生错误 这是卡夫卡制作人的代码: 文件example.model.AmazonProducerExample //更新了用户的建议,谢谢大家如何在Play Framework 2.x中实现对未来对象的隐式Json写入,json,scala,playframework,Json,Scala,Playframework,我是play framework的新手,我想定期向amazon询问一些产品,以便将它们插入到kafka主题中,当我尝试编译代码时会发生错误 这是卡夫卡制作人的代码: 文件example.model.AmazonProducerExample //更新了用户的建议,谢谢大家 package example.utils import jodd.lagarto.dom.{NodeSelector, LagartoDOMBuilder} import example.model.AmazonProdu
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] ^
我读过这篇文章,但它对我不起作用
有人能帮我吗
写入[T]
生成Json。如果不进行阻止,您无法直接从Future
生成它
但是,您可以在将来添加“回调”,如下所示:
amazonPageParser.parse(productId).onSuccess { case amazonProduct =>
producer.send(Json.toJson(amazonProduct).toString)
}
或者使用其他未来的方法,如
map
或foreach
写入[T]
生成Json。如果不进行阻止,您无法直接从Future
生成它
但是,您可以在将来添加“回调”,如下所示:
amazonPageParser.parse(productId).onSuccess { case amazonProduct =>
producer.send(Json.toJson(amazonProduct).toString)
}
或者使用其他未来的方法,如
map
或foreach
对于Future[T]
,您最好让Writes[T]
,并在Future
中调用“内部”写操作,谢谢您的回答。据我所知,您指的是对kafka主题的写入操作将在AmazonPageParser.parse方法中,不是吗?但我希望以一种解耦的方式实现此功能……您应该在将来完成后编写,因此使用map
、flatMap
或使用适当的值运算进行理解。对于我来说,这是一个关于理解未来的一般性问题。对于未来[T],你最好让写[T]
,并在未来的“内部”调用写操作,谢谢你的回答。据我所知,您指的是对kafka主题的写入操作将在AmazonPageParser.parse方法中,不是吗?但我希望以一种解耦的方式实现此功能……您应该在将来完成后编写,因此使用map
、flatMap
或使用适当的值运算进行理解。对于我来说,这是一个关于理解未来的一般性问题。谢谢@Tyth和cchantep。我将用解决方案更新线程谢谢@Tyth和cchantep。我将用解决方案更新线程