在scala spray中,有没有办法从Unmarshaller[T]
转换为FromRequestUnmarshaller[T]
。我试图让entity
指令在不使用含义的情况下工作。例如:
...
} ~ post {
path("myPath") {
entity(sprayJsonUnmarshaller[MyCaseClass](myCaseClassRootJsonFormat)) { myCaseClass =>
complete { handle(myCaseClass) }
}
} ~ ...
编译错误:
Multiple markers at this line
- type mismatch; found : spray.httpx.unmarshalling.Unmarshaller[MyCaseClass] (which
expands to) spray.httpx.unmarshalling.Deserializer[spray.http.HttpEntity,MyCaseClass]
required: spray.httpx.unmarshalling.FromRequestUnmarshaller[?] (which expands to)
spray.httpx.unmarshalling.Deserializer[spray.http.HttpRequest,?]
- type mismatch; found : spray.httpx.unmarshalling.Unmarshaller[MyCaseClass] (which
expands to) spray.httpx.unmarshalling.Deserializer[spray.http.HttpEntity,MyCaseClass]
required: spray.httpx.unmarshalling.FromRequestUnmarshaller[?] (which expands to)
spray.httpx.unmarshalling.Deserializer[spray.http.HttpRequest,?]
答案 0 :(得分:1)
在这部分中,Spray在很大程度上取决于隐式分辨率。我可能不正确,但据我所知,现在有简单而优雅的方式来做到这一点。就像它的设计一样,你应该遵循以下指令:entity(as[MyCaseClass])
。然后,如果你看一下as[_]
指令,就没有一个简短的方法可以将一个简单的unmarshaller(它接受一个实体并使你的case类成为)来自fromRequestUnmarshaller(来自HttpRequest - > case class),所有这些都是隐式扩展器可以在[这里]找到(https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/UnmarshallerLifting.scala#L21)。因此,当您致电entity(as[MyCaseClass])
时,它会扩展为:
entity {
as[MyCaseClass] {
fromRequestUnmarshaller[MyCaseClass] {
fromMessageUnmarshaller[MyCaseClass] {
sprayJsonUnmarshaller[MyCaseClass](myCaseClassRootJsonFormat)
}
}
}
}
如果你想让它明确,那么你应该用上面的形式写出来。这样您就可以放弃as[MyCaseClass]
另一方面,您可以选择另一种显式方式 - 提取实体并将其转换为json:
requestInstance { req =>
val json = req.entity.asString.parseJson
json.convertTo(myCaseClassRootJsonFormat)
}