每个 Route 对象只允许有一个子路由器
Only one sub router per Route object is allowed
我使用 Vert.x 创建了一个网络应用,如下所示:
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router): Unit {
r.route("/api/*")
.subRouter(GenderApi(vertx).create())
.subRouter(InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(private val vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/interests")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
class GenderApi(private val vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll() : Route =
router
.get("/genders")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
编译器抱怨:
java.lang.IllegalStateException: Only one sub router per Route object is allowed.
at io.vertx.ext.web.impl.RouteImpl.subRouter(RouteImpl.java:161)
at io.databaker.MainVerticle.apiResource(MainVerticle.kt:15)
at io.databaker.MainVerticle.start(MainVerticle.kt:33)
at io.vertx.core.impl.DeploymentManager.lambda$doDeploy(DeploymentManager.java:196)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:96)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:59)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext[=11=](EventLoopContext.java:40)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
如何解决?
我想我用 误导了你。
Vertx 4 的正确语法是:
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router) {
r.route("/api/genders*")
.subRouter(GenderApi(vertx).create())
r.route("/api/interests*")
.subRouter(InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
println(http.cause())
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
class GenderApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
如果您打算将 Interests
用作资源,则在 Vert.x 中使用子路由器是有意义的。
那么你会得到类似的东西:
router.get(...)
router.post(...)
不过,有一种更好的方法可以实现该功能。您可以使用 mountSubRouter
:
而不是使用 subRouter
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router) {
r.mountSubRouter("/api/", GenderApi(vertx).create())
r.mountSubRouter("/api/", InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
println(http.cause())
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/interests")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am interests path");
}
fun create(): Router = router
}
class GenderApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/genders")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
请注意,使用mountSubRouter
时,/api/*
后不需要*
,事实上,这会产生错误。
我使用 Vert.x 创建了一个网络应用,如下所示:
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router): Unit {
r.route("/api/*")
.subRouter(GenderApi(vertx).create())
.subRouter(InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(private val vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/interests")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
class GenderApi(private val vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll() : Route =
router
.get("/genders")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
编译器抱怨:
java.lang.IllegalStateException: Only one sub router per Route object is allowed.
at io.vertx.ext.web.impl.RouteImpl.subRouter(RouteImpl.java:161)
at io.databaker.MainVerticle.apiResource(MainVerticle.kt:15)
at io.databaker.MainVerticle.start(MainVerticle.kt:33)
at io.vertx.core.impl.DeploymentManager.lambda$doDeploy(DeploymentManager.java:196)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:96)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:59)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext[=11=](EventLoopContext.java:40)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
如何解决?
我想我用
Vertx 4 的正确语法是:
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router) {
r.route("/api/genders*")
.subRouter(GenderApi(vertx).create())
r.route("/api/interests*")
.subRouter(InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
println(http.cause())
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
class GenderApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
如果您打算将 Interests
用作资源,则在 Vert.x 中使用子路由器是有意义的。
那么你会得到类似的东西:
router.get(...)
router.post(...)
不过,有一种更好的方法可以实现该功能。您可以使用 mountSubRouter
:
subRouter
class MainVerticle : AbstractVerticle() {
private fun apiResource(r: Router) {
r.mountSubRouter("/api/", GenderApi(vertx).create())
r.mountSubRouter("/api/", InterestApi(vertx).create())
}
private fun rootResource(r: Router): Unit {
r.route("/").handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am healthy");
}
}
override fun start(startPromise: Promise<Void>) {
val server = vertx.createHttpServer()
val router = Router.router(vertx)
apiResource(router)
rootResource(router)
server.requestHandler(router).listen(8888) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8888")
} else {
println(http.cause())
startPromise.fail(http.cause());
}
}
}
}
class InterestApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/interests")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am interests path");
}
fun create(): Router = router
}
class GenderApi(vertx: Vertx) {
private val router = Router.router(vertx)
init {
readAll()
}
private fun readAll(): Route =
router
.get("/genders")
.handler {
val res = it.response()
res.putHeader("content-type", "text/plain");
// Write to the response and end it
res.end("I am genders path");
}
fun create(): Router = router
}
请注意,使用mountSubRouter
时,/api/*
后不需要*
,事实上,这会产生错误。