Scala Akka HTTP转换参数为java.time.ZonedDateTime

arc*_*zee 1 scala akka akka-http

我正在使用Akka HTTP(在Scala中)开发REST服务.我想要一个传递给http get请求的参数转换为ZonedDateTime类型.如果我尝试使用String或Int但是使用ZonedDateTime类型失败,代码工作正常.代码看起来像这样:

parameters('testparam.as[ZonedDateTime])
Run Code Online (Sandbox Code Playgroud)

这是我看到的错误:

Error:(23, 35) type mismatch;
 found   : akka.http.scaladsl.common.NameReceptacle[java.time.ZonedDateTime]
 required: akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet
          parameters('testparam.as[ZonedDateTime]){
Run Code Online (Sandbox Code Playgroud)

如果我向列表添加多个参数,我会得到一个不同的错误:

Error:(23, 21) too many arguments for method parameters: (pdm: akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet)pdm.Out
          parameters('testparam.as[ZonedDateTime], 'testp2){
Run Code Online (Sandbox Code Playgroud)

我发现这个文档中,当我研究这个问题http://doc.akka.io/japi/akka-stream-and-http-experimental/2.0/akka/http/scaladsl/server/directives/ParameterDirectives.html和我尝试了import akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet使用Scala 2.11 添加的解决方法,但问题仍然存在.

有人可以解释一下我做错了什么以及为什么ZonedDateTime类型不起作用?提前致谢!

这是一个代码片段,应该重现我所看到的问题

import java.time.ZonedDateTime

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer

import scala.io.StdIn


object WebServer {
  def main(args: Array[String]) {

    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    // needed for the future flatMap/onComplete in the end
    implicit val executionContext = system.dispatcher

    val route =
      path("hello") {
        get {
          parameters('testparam.as[ZonedDateTime]){
            (testparam) =>
              complete(testparam.toString)
          }
        }
      }

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)

    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine() // let it run until user presses return
    bindingFuture
      .flatMap(_.unbind()) // trigger unbinding from the port
      .onComplete(_ => system.terminate()) // and shutdown when done
  }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*tti 7

由于ZonedDateTimeAkka-HTTP本身没有编组,您需要为该parameters指令提供自定义的unmarshaller .

此功能在此处的文档中进行了简要描述.

您可以通过使用Unmarshaller.strict例如函数来创建您的unmarshaller

  val stringToZonedDateTime = Unmarshaller.strict[String, ZonedDateTime](ZonedDateTime.parse)
Run Code Online (Sandbox Code Playgroud)

此示例假定您的param以ISO格式提供.如果不是,则需要修改解组功能.

然后,您可以使用unmarshaller将其传递给parameters指令:

parameters("testparam".as(stringToZonedDateTime)){
            (testparam) =>
              complete(testparam.toString)
          }
Run Code Online (Sandbox Code Playgroud)