在spala的喷射中,从普通的Unmarshaller获得一个FromRequestUnmarshaller

时间:2014-06-25 23:31:13

标签: scala spray

在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,?]

1 个答案:

答案 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)
}