如何将 akka http 请求实体解组为字符串?
How to unmarshall akka http request entity as string?
我正在尝试将请求负载解组为字符串,但由于某种原因它失败了。我的代码:
path("mypath") {
post {
decodeRequest {
entity(as[String]) {jsonStr => //could not find implicit value for...FromRequestUnmarshaller[String]
complete {
val json: JsObject = Json.parse(jsonStr).as[JsObject]
val jsObjectFuture: Future[JsObject] = MyDatabase.addListItem(json)
jsObjectFuture.map(_.as[String])
}
}
}
}
}
例如,在这个 SO thread 中,默认情况下似乎应该可以使用此隐式。但也许这在 akka-http 中有所不同?
我尝试导入具有 stringUnmarshaller
的 akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers
,但没有帮助。可能是因为这个 returns 类型 FromEntityUnmarshaller[String]
而不是 FromRequestUnmarshaller[String]
。 spray.httpx.unmarshalling.BasicUnmarshallers
中还有一个字符串解组器,但这也无济于事,akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers
我如何解组(和编组)成一个字符串?
(奖励:如何直接在 JsObject 中解组(播放 json)。但也只有字符串,因为我对为什么这不起作用很感兴趣,它可能对其他情况有用)。
使用 1.0-RC3
谢谢。
只要范围内有正确的隐式,您的代码应该没问题。如果你在范围内有一个隐式 FlowMaterializer
那么事情应该按预期工作,因为编译代码显示:
import akka.http.scaladsl.server.Route
import akka.actor.ActorSystem
import akka.stream.ActorFlowMaterializer
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Directives._
import akka.stream.FlowMaterializer
implicit val system = ActorSystem("test")
implicit val mater = ActorFlowMaterializer()
val routes:Route = {
post{
decodeRequest{
entity(as[String]){ str =>
complete(OK, str)
}
}
}
}
如果您想更进一步并解组为 JsObject
,那么您只需要一个范围内的隐式 Unmarshaller
来处理该转换,如下所示:
implicit val system = ActorSystem("test")
implicit val mater = ActorFlowMaterializer()
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.http.scaladsl.model.HttpEntity
implicit val um:Unmarshaller[HttpEntity, JsObject] = {
Unmarshaller.byteStringUnmarshaller.mapWithCharset { (data, charset) =>
Json.parse(data.toArray).as[JsObject]
}
}
val routes:Route = {
post{
decodeRequest{
entity(as[String]){ str =>
complete(OK, str)
}
}
} ~
(post & path("/foo/baz") & entity(as[JsObject])){ baz =>
complete(OK, baz.toString)
}
}
我正在尝试将请求负载解组为字符串,但由于某种原因它失败了。我的代码:
path("mypath") {
post {
decodeRequest {
entity(as[String]) {jsonStr => //could not find implicit value for...FromRequestUnmarshaller[String]
complete {
val json: JsObject = Json.parse(jsonStr).as[JsObject]
val jsObjectFuture: Future[JsObject] = MyDatabase.addListItem(json)
jsObjectFuture.map(_.as[String])
}
}
}
}
}
例如,在这个 SO thread 中,默认情况下似乎应该可以使用此隐式。但也许这在 akka-http 中有所不同?
我尝试导入具有 stringUnmarshaller
的 akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers
,但没有帮助。可能是因为这个 returns 类型 FromEntityUnmarshaller[String]
而不是 FromRequestUnmarshaller[String]
。 spray.httpx.unmarshalling.BasicUnmarshallers
中还有一个字符串解组器,但这也无济于事,akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers
我如何解组(和编组)成一个字符串?
(奖励:如何直接在 JsObject 中解组(播放 json)。但也只有字符串,因为我对为什么这不起作用很感兴趣,它可能对其他情况有用)。
使用 1.0-RC3
谢谢。
只要范围内有正确的隐式,您的代码应该没问题。如果你在范围内有一个隐式 FlowMaterializer
那么事情应该按预期工作,因为编译代码显示:
import akka.http.scaladsl.server.Route
import akka.actor.ActorSystem
import akka.stream.ActorFlowMaterializer
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Directives._
import akka.stream.FlowMaterializer
implicit val system = ActorSystem("test")
implicit val mater = ActorFlowMaterializer()
val routes:Route = {
post{
decodeRequest{
entity(as[String]){ str =>
complete(OK, str)
}
}
}
}
如果您想更进一步并解组为 JsObject
,那么您只需要一个范围内的隐式 Unmarshaller
来处理该转换,如下所示:
implicit val system = ActorSystem("test")
implicit val mater = ActorFlowMaterializer()
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.http.scaladsl.model.HttpEntity
implicit val um:Unmarshaller[HttpEntity, JsObject] = {
Unmarshaller.byteStringUnmarshaller.mapWithCharset { (data, charset) =>
Json.parse(data.toArray).as[JsObject]
}
}
val routes:Route = {
post{
decodeRequest{
entity(as[String]){ str =>
complete(OK, str)
}
}
} ~
(post & path("/foo/baz") & entity(as[JsObject])){ baz =>
complete(OK, baz.toString)
}
}