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具有 astringUnmarshaller但它没有帮助。也许是因为这返回类型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) 
      }
    }
  }    
}

如果您想更进一步并解组到 aJsObject那么您只需要一个隐式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 回答