我已经完成了关于SO的文档和许多问题,但仍然无法弄清楚我做错了什么。
我开始使用vanilla akka http g8模板,但我想使用特征而不是案例类来表示POST请求中的对象。
当使用案例类时,我的应用程序中的一切都很好,但是当我尝试实现特征时它失败了:
[error] CollectionRoutes.scala:38: could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[collector.CollectorConfig]
[error] entity(as[CollectorConfig]) { config =>
[error] ^
[error] CollectionRoutes.scala:55: could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[collector.CollectorStep]
[error] entity(as[CollectorStep]) { collstep =>
[error] ^
[error] CollectionRoutes.scala:77: could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[collector.CollectorConfig]
[error] entity(as[CollectorConfig]) { config =>
[error] ^
[error] three errors found
这是我用来定义json格式的特性:
trait JsonSupport extends DefaultJsonProtocol {
import spray.json._
implicit val collectionTypeConverter = new EnumJsonConverter(CollectionType)
implicit val actionPerformedJsonFormat = jsonFormat1(ActionPerformed)
implicit val restCollectorStepFormat = jsonFormat3(RestCollectorStep)
implicit object collectorStepFormat extends RootJsonFormat[CollectorStep] {
def write(a: CollectorStep) = a match {
case p: RestCollectorStep => p.toJson
}
def read(value: JsValue) =
value.asJsObject.fields("collectionType") match {
case JsString("Rest") => value.convertTo[RestCollectorStep]
}
}
implicit val restCollectorConfigFormat = jsonFormat5(RestCollectorConfig)
implicit object collectorConfigFormat extends RootJsonFormat[CollectorConfig] {
def write(a: CollectorConfig) = a match {
case p: RestCollectorConfig => p.toJson
}
def read(value: JsValue) =
value.asJsObject.fields("collectionType") match {
case JsString("Rest") => value.convertTo[RestCollectorConfig]
}
}
}
这是定义我的路线的特征:
trait CollectionRoutes extends JsonSupport {
import spray.json._
implicit def system: ActorSystem
lazy val log = Logging(system, classOf[CollectionRoutes])
def collectorRegistryActor: ActorRef
implicit lazy val timeout = Timeout(5.seconds) // usually we'd obtain the timeout from the system's configuration
val settings = CorsSettings.defaultSettings.withAllowGenericHttpRequests(true)
lazy val collectionRoutes: Route = cors(settings) {
pathPrefix("createcollector") {
concat(
pathEnd {
concat(
post {
entity(as[CollectorConfig]) { config =>
val collectorCreated: Future[CollectorRegistryActor.ActionPerformed] =
(collectorRegistryActor ? MakeCollector(config)).mapTo[CollectorRegistryActor.ActionPerformed]
onSuccess(collectorCreated) { created =>
complete(created.description)
}
}
}
)
}
)
} ~
pathPrefix("reststep") {
concat(
pathEnd {
concat(
post {
entity(as[CollectorStep]) { collstep =>
val executionResult: Future[StepActor.StepResponse] = (collectorRegistryActor ? ExecuteStep(collstep)).mapTo[StepActor.StepResponse]
onSuccess(executionResult) { res =>
res match {
case StepActor.StepResult(step, response, result) => {
val res = (response :: result :: Nil).toJson.toString
complete(res)
}
case StepActor.StepError(step, error) => complete(error)
}
}
}
}
)
}
)
} ~
pathPrefix("restcollect") {
concat(
pathEnd {
concat(
post {
entity(as[CollectorConfig]) { config =>
val executionResult: Future[CollectorActor.CollectionResult] = (collectorRegistryActor ? ExecuteCollection(config)).mapTo[CollectorActor.CollectionResult]
onSuccess(executionResult) { response =>
complete(response.result)
}
}
}
)
}
)
}
}
}
这就是这种特性的使用方式。
object CollectionServer extends App with CollectionRoutes {
implicit val system: ActorSystem = ActorSystem("CollectionServer")
implicit val materializer: ActorMaterializer = ActorMaterializer()
val collectorRegistryActor: ActorRef = system.actorOf(CollectorRegistryActor.props, "collectorRegistryActor")
lazy val routes: Route = collectionRoutes
Http().bindAndHandle(routes, "localhost", 9100)
println(s"Server online at http://localhost:9100/")
Await.result(system.whenTerminated, Duration.Inf)
}
我感到困惑,因为我相信我已经以一种非常标准的方式设置了所有内容,但它并没有意识到这一点。
任何想法都赞赏 - 谢谢。
答案 0 :(得分:0)
想出来:
我应该一直在扩展SprayJsonSupport而不是DefaultJsonProtocol
trait JsonSupport extends SprayJsonSupport {