Scala - 喷射调用路径如何进行(调试喷射代码)
Scala - How spray call path goes (Debugging spray code)
我是 Scala、Spray 和函数式编程的新手。我很伤心,我仍然无法理解 Spray RestAPI 的基本示例。
我已经按照这篇博客post中给出的说明编写了程序。
http://www.smartjava.org/content/first-steps-rest-spray-and-scala
我的 Route 函数如下所示。
val aSimpleRoute =
path("path1") {
println("in path path1..")
put {
println("in path path1/put..")
respondWithMediaType(MediaTypes.`text/html`) {
complete {
<h1>in path path1/put..</h1>
}
}
} ~ get {
println("in path path1/get..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path1/get..</h1>
}
}
}
} ~
path("path2") {
println("in path path2..")
get {
println("in path path2/get..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path2/get..</h1>
}
}
} ~ post {
println("in path path2/post..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path2/post..</h1>
}
}
}
}
一切正常。但我的问题是,当我的程序启动时,它将 运行 通过接收函数。查看我的 println 输出,当程序启动时(在它处理任何 http 请求之前)
in path path1..
in path path1/put..
in path path1/get..
in path path2..
in path path2/get..
in path path2/post..
[INFO] [09/14/2015 12:56:01.364] [on-spray-can-akka.actor.default-dispatcher-4] [akka://on-spray-can/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8080
所以我不明白为什么程序在启动时会进入所有可能的调用路径。
而且,当收到 HTTP 请求时,这些 println 都没有达到。
谁能解释为什么?
好吧,你使用“val”来声明喷雾路线,这是正常行为,因为当你运行你的程序时,Scala 初始化 vals,如果你将“lazy val”而不是“val”你当您显式使用此 val 时,将会看到您将获得打印。
例如:
val a = {
println("val a initialization")
"val a initialization"
}
lazy val b = {
println("using of val b")
"using of val b"
}
println("use of Val a " + a)
println("use of val b " + b)
结果:
val a initialization
use of Val a val a initialization
using of val b
use of val b using of val b
您可以在这里找到解释:Understanding extractions
简而言之,非叶和非参数化(没有提取)指令仅在构建路由时执行一次。叶指令(如 complete
)仅在请求命中指令的路由时执行。参数化指令(以及其中的所有内容)按请求执行(因为提取的参数每次都不同)——即使指令本身在已经接受该请求的指令之后。
在您的情况下,您在非叶和非参数化指令中有 println
s,因此它们仅在初始化时执行一次。如果您希望它们根据可接受的请求执行 - 只需将它们移入 complete
:
val aSimpleRoute =
path("path1") {
put {
respondWithMediaType(MediaTypes.`text/html`) {
complete {
println("in path path1/put..")
<h1>in path path1/put..</h1>
}
}
} ~ get {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path1/get..")
<h1>in path path1/get..</h1>
}
}
}
} ~
path("path2") {
get {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path2/get..")
<h1>in path path2/get..</h1>
}
}
} ~ post {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path2/post..")
<h1>in path path2/post..</h1>
}
}
}
讨论是here
我是 Scala、Spray 和函数式编程的新手。我很伤心,我仍然无法理解 Spray RestAPI 的基本示例。
我已经按照这篇博客post中给出的说明编写了程序。 http://www.smartjava.org/content/first-steps-rest-spray-and-scala
我的 Route 函数如下所示。
val aSimpleRoute =
path("path1") {
println("in path path1..")
put {
println("in path path1/put..")
respondWithMediaType(MediaTypes.`text/html`) {
complete {
<h1>in path path1/put..</h1>
}
}
} ~ get {
println("in path path1/get..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path1/get..</h1>
}
}
}
} ~
path("path2") {
println("in path path2..")
get {
println("in path path2/get..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path2/get..</h1>
}
}
} ~ post {
println("in path path2/post..")
respondWithMediaType(MediaTypes.`application/json`) {
complete {
<h1>in path path2/post..</h1>
}
}
}
}
一切正常。但我的问题是,当我的程序启动时,它将 运行 通过接收函数。查看我的 println 输出,当程序启动时(在它处理任何 http 请求之前)
in path path1..
in path path1/put..
in path path1/get..
in path path2..
in path path2/get..
in path path2/post..
[INFO] [09/14/2015 12:56:01.364] [on-spray-can-akka.actor.default-dispatcher-4] [akka://on-spray-can/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8080
所以我不明白为什么程序在启动时会进入所有可能的调用路径。 而且,当收到 HTTP 请求时,这些 println 都没有达到。
谁能解释为什么?
好吧,你使用“val”来声明喷雾路线,这是正常行为,因为当你运行你的程序时,Scala 初始化 vals,如果你将“lazy val”而不是“val”你当您显式使用此 val 时,将会看到您将获得打印。
例如:
val a = {
println("val a initialization")
"val a initialization"
}
lazy val b = {
println("using of val b")
"using of val b"
}
println("use of Val a " + a)
println("use of val b " + b)
结果:
val a initialization
use of Val a val a initialization
using of val b
use of val b using of val b
您可以在这里找到解释:Understanding extractions
简而言之,非叶和非参数化(没有提取)指令仅在构建路由时执行一次。叶指令(如 complete
)仅在请求命中指令的路由时执行。参数化指令(以及其中的所有内容)按请求执行(因为提取的参数每次都不同)——即使指令本身在已经接受该请求的指令之后。
在您的情况下,您在非叶和非参数化指令中有 println
s,因此它们仅在初始化时执行一次。如果您希望它们根据可接受的请求执行 - 只需将它们移入 complete
:
val aSimpleRoute =
path("path1") {
put {
respondWithMediaType(MediaTypes.`text/html`) {
complete {
println("in path path1/put..")
<h1>in path path1/put..</h1>
}
}
} ~ get {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path1/get..")
<h1>in path path1/get..</h1>
}
}
}
} ~
path("path2") {
get {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path2/get..")
<h1>in path path2/get..</h1>
}
}
} ~ post {
respondWithMediaType(MediaTypes.`application/json`) {
complete {
println("in path path2/post..")
<h1>in path path2/post..</h1>
}
}
}
讨论是here