import io.vertx.core.Vertx
import io.vertx.core.http.HttpMethod
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.CorsHandler
class RestfulServer(
vertx: Vertx,
private val ipAddress: String,
private val port: Int
) {
private val httpServer = vertx.createHttpServer()
private val router: Router = Router.router(vertx)
init {
corsHandling()
createRouter()
}
private fun corsHandling(): Route =
router.route().handler {
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}
private fun createRouter() =
router.get("/").blockingHandler { ctx ->
val response = ctx.response()
response.putHeader("content-type", "application/json")
response.end("""{}""")
}
fun listen() {
httpServer.requestHandler(router).listen(port, ipAddress)
}
fun close() {
httpServer.close()
}
}
当我运行上面的代码时,其余的API调用挂在浏览器中,但如果我注释掉函数corsHandling()
,一切都很好。
我发现这不是CorsHandler
的问题,而是我如何在kotlin中调用该函数的问题。
工作功能:
private fun corsHandling(): Route =
router.route().handler( // here I use ()
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
)
这个挂起:
private fun corsHandling(): Route =
router.route().handler{ // here I use {}
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}
正如您所看到的,唯一的区别是router.route().handler
调用中的{}而不是((。在kotlin中,如果lambda是最后一个参数,则可以省略函数调用。
这个问题可能更多地针对Kotlin而不是Vert.x
它是处理程序的函数定义https://vertx.io/docs/apidocs/io/vertx/ext/web/Route.html#handler-io.vertx.core.Handler-
实际问题是我正在调用处理程序函数,如处理程序({{lambda}}(
@ivo已经有了答案,但只是用一个简单的例子来澄清
fun takesSingleLambda(func: ()-> Unit) {
func()
}
fun main() {
println("1")
takesSingleLambda(
returnsLambda()
)
println("2")
takesSingleLambda{
returnsLambda()
}
println("3, which does exactly the same as 2")
takesSingleLambda({
returnsLambda()
})
}
fun returnsLambda() = { //this is similar to CorsHandler.create("*").allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
println("executing")
}
简单地说:
functionName{
}
与相同
functionName({
})
,而不是
functionName(
)
所以当你写的时候
router.route().handler{
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}
你实际上在写
router.route().handler({
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
})
也就是说,你将一个lambda封装在另一个lambda。当它试图执行处理程序时,它只是创建你希望它处理的处理程序,而不是执行它。我希望这是有意义的。
我将使用Android和Views上的点击监听器的一个例子。
onClick监听器的Java代码
interface OnClickListener {
void onClick(View view)
}
OnClickListener listener = new OnClickListener() {
override void onClick(View view) {
//on click stuff
}
}
在OnClick方法中,您有一个对事件源自的视图的引用。同样的东西可以在Kotlin中使用{}创建。
val listener: OnClickListener = {
// Where is the view reference?
}
它是lambda函数的隐式参数
val listenerExplicit: OnClickListener = { view ->
// there it is
}
因此,如果你想将其应用于按钮
button.setOnClickListener {
// This is already the inside on the onClick method
}
所以当你有这个:
private fun corsHandling(): Route =
router.route().handler {
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}
您创建了一个处理程序{},而该处理程序所做的只是创建CorsHandler并将其丢弃。
这也应该起作用,但只是表明什么没有发生,你想发生什么。
private fun corsHandling(): Route =
router.route().handler { event ->
val fooHandler = CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
fooHandler.handle(event)
}