我想编写一个通用的提取器,使用spray和spray-json解析json POST请求体。
但是,我在尝试将其与多个模型一起使用时遇到了困难。以下是服务对象中的case语句:
import MyJsonProtocol._
...
def receive = {
case Post (Routes.person.post, p: Person) => sender ! Ok(Actions.person.post(p))
case Get (Routes.foo.forId(x)) => sender ! Ok(x)
case _ => sender ! Ok("No handler")
}
以下是我编写的提取器(只要在case语句的作用域内存在单个模型的JsonReader即可工作):
//NB. Json.parse returns an Option[T]
object Post extends Request {
def unapply[T:JsonReader](req: HttpRequest): Option[(String, T)] = req match {
case HttpRequest(POST, url, _, HttpBody(_, body), _) => Json.parse[T](body.asString).map((url, _))
case _ => None
}
}
然而,一旦我添加了新的模型(及其相关的JsonReader),这段代码就无法编译,并显示如下错误:
ambiguous implicit values:
[error] both value personFormat in object Json of type => spray.json.RootJsonFormat[com.rsslldnphy.foam.models.Person]
[error] and value animalFormat in object Json of type => spray.json.RootJsonFormat[com.rsslldnphy.foam.models.Animal]
[error] match expected type spray.json.JsonReader[T]
[error] case Post (Routes.person.post, p: Person) => sender ! Ok(Actions.person.post(p))
JsonReaders的通用类型不同的事实似乎被忽略了。这是类型擦除吗?有没有办法绕过它来获得我想要的结果?
这是目前项目的完整可编译代码,其中ExampleService
中的注释解释了它的问题所在:github.com/rsslldnphy/foam。非常感谢您的帮助。如果目前无法实现我的需求,是否有其他替代方法可以建议?
case Post[Person]
吗? - Kim Stebel