我有这样的事情:
case HttpRequest(POST, Uri.Path("/userAction"), headers, entity: HttpEntity.NonEmpty, protocol) =>
val x = entity.as[spray.http.FormData].merge.asInstanceOf[spray.http.FormData].fields
sender ! HttpResponse(entity="Got it: " + x)
打开HttpEntity
似乎有点不方便,有更优雅的方式吗?
此外:是否可以从具有多个delacred变量的输入中获取数据?有没有更好的方法来访问FormData,例如作为Json还是HashMap?
答案 0 :(得分:3)
您是否真的有理由使用喷雾罐实施此操作?在路由中,它更容易和自然:
lazy val yourRoute: Route = {
(post & path("userAction")) {
entity(as[SomeType]) { data =>
// do what you want
}
}
}
在这个版本中,它都适用于您的类型(SomeType
)的正确解组。但是如果你想坚持使用喷雾罐,你可以使用spray-httpx unmarshaller。我没有IDE靠近我,但这可能是这样的(我的项目实际代码中有一些Scalaz技巧):
case request @ HttpRequest(...) =>
fromTryCatch(request.entity |> unmarshal[SomeType]) // returns Throwable \/ SomeType, like scala's Either type
这里也是正确的unmarshaller,例如,如果你想让你的实体以Json格式(即喷JsObject),那么你需要发出一个带有json有效负载的请求,写entity(as[JsObject])
并提供一个隐含的来自spray.json.SprayJsonSupport
的unmarshaller。我认为对FormData
使用这种方法有点开销,因为简单的Post有效负载你有formFields
指令,你可以写:
lazy val yourRoute: Route = {
(post & path("userAction")) {
formFields(...) { fields => // just enumerate field names from your FormData
// do what you want
}
}
}
对于Map方法,如果相同,只需将spray.json.DefaultJsonProtocol
添加到范围中,即可为地图添加unmarshaller。
仍然使用喷涂路由DSL比处理低级别的代码要好得多。如果您仍想使用,请查看spray.httpx.unmarshalling
包,它包含不同类型的解组,用于实体,请求和响应。