13

リクエスト ペイロードを文字列として非整列化しようとしていますが、何らかの理由で失敗しています。私のコード:

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 では異なるのでしょうか?

akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallersを持っているインポートを試みましたstringUnmarshallerが、役に立ちません。たぶん、これは type FromEntityUnmarshaller[String]not を返すためFromRequestUnmarshaller[String]です。文字列アンマーシャラーもありますspray.httpx.unmarshalling.BasicUnmarshallersが、これも役に立ちません。akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers

文字列にアンマーシャリング (およびマーシャリング) するにはどうすればよいですか?

(ボーナス: JsObject で直接アンマーシャリングする方法 (json を再生)。ただし、これが機能しない理由に興味があり、他の場合に役立つ可能性があるため、文字列のみ)。

1.0-RC3 の使用

ありがとう。

4

1 に答える 1

18

スコープ内に適切な暗黙があれば、コードは問題ないはずです。スコープに暗黙的なものがある場合は、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) 
      }
    }
  }    
}

さらに一歩進んで a にアンマーシャリングしたい場合は、その変換を処理するための暗黙的なスコープ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)
  }    
}
于 2015-06-15T13:06:12.797 に答える