Scala Akka HTTP 转换参数为 java.time.ZonedDateTime [英] Scala Akka HTTP casting parameter as java.time.ZonedDateTime
问题描述
我正在使用 Akka HTTP(在 Scala 中)开发 REST 服务.我希望将传递给 http get 请求的参数转换为 ZonedDateTime 类型.如果我尝试使用 String 或 Int 但由于 ZonedDateTime 类型失败,则代码工作正常.代码如下所示:
I'm working on a REST service using Akka HTTP (in Scala). I would like a parameter that is passed in to a http get request to be converted to the ZonedDateTime type. The code works fine if I try to use String or Int but fails with a ZonedDateTime type. The code would look like so:
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]){
如果我向列表中添加多个参数,则会出现不同的错误:
If I add more than one parameter to the list I get a different error:
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 的解决方法,但问题仍然存在.
I found this in the documentation when I was researching the problem http://doc.akka.io/japi/akka-stream-and-http-experimental/2.0/akka/http/scaladsl/server/directives/ParameterDirectives.html and I tried the workaround of adding import akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet
along with using Scala 2.11 but the problem persisted.
有人可以解释一下我做错了什么以及为什么 ZonedDateTime 类型不起作用吗?提前致谢!
Could someone please explain what I'm doing wrong and why the ZonedDateTime type doesn't work? Thanks in advance!
这是一个代码片段,可以重现我看到的问题
Here is a code snippet that should reproduce the problem I'm seeing
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/
Press 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
}
}
推荐答案
由于 ZonedDateTime
不是 Akka-HTTP 本身解组的,您需要为 parameters<提供自定义解组器/code> 指令.
As ZonedDateTime
is not natively unmarshalled by Akka-HTTP, you will need to provide a custom unmarshaller to the parameters
directive.
文档中简要描述了此功能此处.
This functionality is briefly described in the docs here.
可以使用 Unmarshaller.strict
从函数创建解组器,例如
Your unmarshaller can be created from a function by using Unmarshaller.strict
, e.g.
val stringToZonedDateTime = Unmarshaller.strict[String, ZonedDateTime](ZonedDateTime.parse)
此示例假设您的参数以 ISO 格式提供.如果不是,则需要修改解组函数.
This example assumes your param is provided in an ISO format. If it's not, you'll need to amend the unmarshalling function.
然后您可以使用解组器将其传递给参数指令:
You can then use the unmarshaller passing it to the parameters directive:
parameters('testparam.as(stringToZonedDateTime)){ testparam =>
complete(testparam.toString)
}
这篇关于Scala Akka HTTP 转换参数为 java.time.ZonedDateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!