リクエストペイロードを文字列としてアンマーシャリングしようとしていますが、何らかの理由で失敗します。私のコード:
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スレッド たとえば、この暗黙的なものはデフォルトで使用可能であるはずです。しかし、おそらくこれはakka-httpでは異なりますか?
stringUnmarshaller
を持つakka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers
をインポートしようとしましたが、役に立ちません。おそらく、これはFromEntityUnmarshaller[String]
ではなくタイプFromRequestUnmarshaller[String]
を返すためです。 spray.httpx.unmarshalling.BasicUnmarshallers
には文字列unmarshallerもありますが、これも役に立ちません。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)
}
}