在 Ktor 应用程序模块而不是 Main 中获取命令行参数?
Posted
技术标签:
【中文标题】在 Ktor 应用程序模块而不是 Main 中获取命令行参数?【英文标题】:Get command line arguments in Ktor Application module instead of Main? 【发布时间】:2019-12-06 07:50:05 【问题描述】:我正在尝试从 Ktor 构建一个应用程序,该应用程序最终应该通过 fatjar 执行。 fatjar 允许使用如下参数:
java -jar myApp.jar XXXXX YYYYY
我知道如何在主模块中获取XXXXX
(通过使用简单的args[0]
),但我无法在应用程序模块中获取该值。
我想做这样的事情:
fun main(args: Array<String>)
val port = System.getenv("PORT")?.toInt() ?: 8080
val status = args[0]
embeddedServer(Netty, port = port, module = (Application::mainModule())).start(wait = true)
fun Application.mainModule()
routing
get("/status")
call.respondText(
<status variable from main function>,
contentType = ContentType.Text.html
)
【问题讨论】:
【参考方案1】:您可以将module
参数的方法引用替换为普通的 lambda。
在这个 lambda 中,您可以使用所需的参数调用模块函数:
fun Application.mainModule(args: Array<String>)
routing
get("/status")
//...
fun main(args: Array<String>)
val server = embeddedServer(Netty, port = 8080)
mainModule(args)
server.start(wait = true)
详情
函数embeddedServer
有module
作为最后一个参数。参数类型为Application
类型的函数,不带任何参数,以Unit
为返回值:
fun embeddedServer(..., module: Application.() -> Unit) : TEngine
这就是您可以提供Application::mainModule
a 作为函数参考的原因。它与参数的类型定义完全匹配。但是你也可以提供一个尾随 lambda 而不是这个函数引用:
val server = embeddedServer(Netty, port = 8080)
// this is Application
routing
get("/status")
//...
在此 lambda 中,this
的类型为 Application
,与您的函数 Application.mainModule
完全相同。这意味着在这个 lambda 中,您可以轻松调用 Application
类型的其他函数。在我的回答中,我使用 args
作为参数创建了 Application.mainModule
,并在尾随 lambda 中调用此函数。
【讨论】:
这很好用!!!谢谢你勒内。我现在正在努力理解这实际上是如何工作的......如果你能给我一些关于为什么 lambda 在这里提供帮助的指导,那就太棒了。但这已经很棒了! 谢谢!! 在保持io.ktor.server.netty.EngineMain.main(args)
的功能的同时有什么办法吗?
@daka 请查看我的答案,它应该会有所帮助。【参考方案2】:
要传递新的配置参数,您可以在其前面加上-P:propName=
。
因此,如果您想通过命令行传递名为 csv
的属性,您可以执行以下操作:
fun main(args: Array<String>)
val csvFileName = "-P:csv=$args[0]"
EngineMain.main(arrayOf(csvFileName))
您也可以通过使用-P:csv=myfile.csv
作为命令行参数来传递参数而无需修改args
。
然后,在您的模块中,您可以通过environment.config.property("csv").getString()
访问它。
fun Application.module()
val csvFileName = environment.config.property("csv").getString()
println(csvFileName)
您可以在the official Ktor documentation 中阅读有关配置 Ktor 应用程序的更多信息。
【讨论】:
谢谢,你觉得你能回答这个问题吗? ***.com/q/66279393/812919以上是关于在 Ktor 应用程序模块而不是 Main 中获取命令行参数?的主要内容,如果未能解决你的问题,请参考以下文章
Ktor App 部署到 AppEngine 时未调用 Main 方法