【问题标题】:Scala Akka HTTP casting parameter as java.time.ZonedDateTimeScala Akka HTTP 转换参数为 java.time.ZonedDateTime
【发布时间】:2017-07-28 22:12:23
【问题描述】:

我正在使用 Akka HTTP(在 Scala 中)开发 REST 服务。我希望将传递给 http get 请求的参数转换为 ZonedDateTime 类型。如果我尝试使用 String 或 Int 但使用 ZonedDateTime 类型失败,则代码可以正常工作。代码如下所示:

parameters('testparam.as[ZonedDateTime])

这是我看到的错误:

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]){

如果我将多个参数添加到列表中,我会收到不同的错误:

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

我在研究问题 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 类型不起作用?提前致谢!

这是一个代码 sn-p 应该重现我看到的问题

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
  }
}

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    由于 ZonedDateTime 本身并未被 Akka-HTTP 解组,因此您需要为 parameters 指令提供自定义解组器。

    文档here 中简要描述了此功能。

    您的解组器可以使用Unmarshaller.strict 从函数创建,例如

    val stringToZonedDateTime = Unmarshaller.strict[String, ZonedDateTime](ZonedDateTime.parse)
    

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

    然后您可以使用解组器将其传递给参数指令:

    parameters('testparam.as(stringToZonedDateTime)){ testparam =>
      complete(testparam.toString)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-06
      • 2018-12-27
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多