如何使用带有 Quarkus 的 Vertx 路由器将所有未找到的路由重定向到 index.html?
How to re-direct all not found routes to index.html using the Vertx router with Quarkus?
我有一个 Quarkus 应用程序,它全部打包了一个 Angular SPA(捆绑在 JAR 中)。 Quarkus 提供后端 API 路由供前端使用。当构建 Quarkus 应用程序时,Angular 应用程序构建被复制到目标中的 META-INF/resources
路径。
我没有使用 JAX-RS 来注册我的路由。相反,我直接在 fun onRouterReady(@Observes router: Router)
方法内以编程方式在 Vertx 路由器上注册它们。
我希望将任何无法识别的路由(作为 Vertx 注册路由或作为静态资源)重定向到 index.html
,以便我的 Angular 应用程序可以加载从它的所有路线。不幸的是,我还没有找到任何方法来做到这一点。
我不知道所有 Quarkus 路由是如何工作的。我怀疑 Quarkus 本身正在使用 Servlet(或者可能是 Vertx)注册一些路由,因为 index.html
在 root 上得到了正确的服务,但是我的身份验证 root 可以防止在没有身份验证的情况下加载。
我尝试了通过搜索找到的各种东西,例如:
router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
context.reroute("index.html)
})
这里的想法是创建一个静态处理程序,然后是一个 catch-all,它会将请求重新写入 index.html
,以便它随后被静态处理程序捕获,但这只会导致一个无限循环(静态处理程序似乎无法找到index.html
)。
我也尝试过通过 JAX-RS 添加过滤器(我想避免这样做),但这也不起作用。
一定有某种方法可以设置它,我确信 Quarkus 代码确实在某处起作用,但我找不到它。非常感谢任何想法。
您需要在应用范围 class 的某处观察 Router
并设置 404 错误处理程序以重定向到 index.html
public void init(@Observes Router router) {
router.errorHandler(404, routingContext -> {
routingContext.response().setStatusCode(302).putHeader("Location", "/index.html").end();
});
}
P.S 使用 routingContext.reroute("index.html");
也可以,但它会保持原来的路径(例如你写 /testabc
,它会显示你的 html 文件但是路径不会是 /index.html
)。如果您确实需要这个,请将其替换为 errorHandler
中的选项
所以,我将在这里回答我自己的问题,因为给定的答案没有满足我的特殊要求。
Quarkus 确实通过独立的 RestEasy class 注册了自己的处理程序(即使 RestEasy 未包含在我的应用程序中)。这包括热重载路由(针对开发模式)、一些安全路由和指向已知静态资源(大概在编译时已知)的静态路由处理程序。
静态资源处理程序的优先级较低,因此是最后调用的处理程序之一。它似乎接受现有的静态资源路径和路由路径(它用作 /index.html
)。
我犯的错误是没有足够仔细地遵循重新路由逻辑。我的代码:
router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
context.reroute("index.html)
})
会拦截任何未与路由匹配的路径并将它们重新路由(我不打算重新定向)到 /index.html
。但是,重新路由会重新启动整个路由过程,因此我使用 /index.html
路径返回到我的 catch-all 处理程序,并再次尝试重新路由它(因为静态处理程序只在很久以后才被调用) .
因此,解决方案是确保我只重新路由我尚未尝试重新路由的路径(并且我可以重新路由到 /
而不是 /index.html
):
router.routeWithRegex("\/.+").handler({ context: RoutingContext ->
context.reroute("/")
})
Quarkus 添加的静态资源处理程序将处理剩下的事情。
我有一个 Quarkus 应用程序,它全部打包了一个 Angular SPA(捆绑在 JAR 中)。 Quarkus 提供后端 API 路由供前端使用。当构建 Quarkus 应用程序时,Angular 应用程序构建被复制到目标中的 META-INF/resources
路径。
我没有使用 JAX-RS 来注册我的路由。相反,我直接在 fun onRouterReady(@Observes router: Router)
方法内以编程方式在 Vertx 路由器上注册它们。
我希望将任何无法识别的路由(作为 Vertx 注册路由或作为静态资源)重定向到 index.html
,以便我的 Angular 应用程序可以加载从它的所有路线。不幸的是,我还没有找到任何方法来做到这一点。
我不知道所有 Quarkus 路由是如何工作的。我怀疑 Quarkus 本身正在使用 Servlet(或者可能是 Vertx)注册一些路由,因为 index.html
在 root 上得到了正确的服务,但是我的身份验证 root 可以防止在没有身份验证的情况下加载。
我尝试了通过搜索找到的各种东西,例如:
router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
context.reroute("index.html)
})
这里的想法是创建一个静态处理程序,然后是一个 catch-all,它会将请求重新写入 index.html
,以便它随后被静态处理程序捕获,但这只会导致一个无限循环(静态处理程序似乎无法找到index.html
)。
我也尝试过通过 JAX-RS 添加过滤器(我想避免这样做),但这也不起作用。
一定有某种方法可以设置它,我确信 Quarkus 代码确实在某处起作用,但我找不到它。非常感谢任何想法。
您需要在应用范围 class 的某处观察 Router
并设置 404 错误处理程序以重定向到 index.html
public void init(@Observes Router router) {
router.errorHandler(404, routingContext -> {
routingContext.response().setStatusCode(302).putHeader("Location", "/index.html").end();
});
}
P.S 使用 routingContext.reroute("index.html");
也可以,但它会保持原来的路径(例如你写 /testabc
,它会显示你的 html 文件但是路径不会是 /index.html
)。如果您确实需要这个,请将其替换为 errorHandler
所以,我将在这里回答我自己的问题,因为给定的答案没有满足我的特殊要求。
Quarkus 确实通过独立的 RestEasy class 注册了自己的处理程序(即使 RestEasy 未包含在我的应用程序中)。这包括热重载路由(针对开发模式)、一些安全路由和指向已知静态资源(大概在编译时已知)的静态路由处理程序。
静态资源处理程序的优先级较低,因此是最后调用的处理程序之一。它似乎接受现有的静态资源路径和路由路径(它用作 /index.html
)。
我犯的错误是没有足够仔细地遵循重新路由逻辑。我的代码:
router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
context.reroute("index.html)
})
会拦截任何未与路由匹配的路径并将它们重新路由(我不打算重新定向)到 /index.html
。但是,重新路由会重新启动整个路由过程,因此我使用 /index.html
路径返回到我的 catch-all 处理程序,并再次尝试重新路由它(因为静态处理程序只在很久以后才被调用) .
因此,解决方案是确保我只重新路由我尚未尝试重新路由的路径(并且我可以重新路由到 /
而不是 /index.html
):
router.routeWithRegex("\/.+").handler({ context: RoutingContext ->
context.reroute("/")
})
Quarkus 添加的静态资源处理程序将处理剩下的事情。