如何使用带有Quarkus的Vertx路由器将所有未找到的路由重定向到index.html?

时间:2020-04-13 22:30:28

标签: java angular kotlin vert.x 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已在根上正确使用,但是我的身份验证根可以阻止未经身份验证的加载。

我尝试了各种通过搜索找到的内容,例如:

router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
    context.reroute("index.html)
})

这里的想法是创建一个静态处理程序,然后是一个包罗万象的程序,它将把请求重新写到index.html,以便随后被静态处理程序捕获,但这只会导致无限循环(静态处理程序似乎无法找到index.html)。

我还尝试过通过JAX-RS添加过滤器(我想避免这种过滤器),但这也不起作用。

必须有某种方法来设置它,并且我确信Quarkus代码实际上在某处起作用,但是我找不到它。任何想法都很感激。

2 个答案:

答案 0 :(得分:1)

您需要在应用程序范围的类中的某个位置观察Router并将404错误处理程序设置为重定向到index.html

public void init(@Observes Router router) {
        router.errorHandler(404, routingContext -> {
            routingContext.response().setStatusCode(302).putHeader("Location", "/index.html").end();
        });
}
使用routingContext.reroute("index.html");

PS也可以使用,但它会保持原样(例如,您编写了/testabc,它将显示您的html文件,但路径不会是/index.html )。如果您确实需要此文件,请用errorHandler

中的选项替换它

答案 1 :(得分:0)

所以,我将在这里回答自己的问题,因为我有给定答案未满足的特殊要求。

Quarkus确实通过RestEasy独立类注册了自己的处理程序(即使RestEasy不包含在我的应用程序中)。其中包括热重载路由(用于dev模式),一些安全路由和指向已知静态资源(可能在编译时已知)的静态路由处理程序。

静态资源处理程序的优先级较低,因此它是最后一个要调用的处理程序之一。它似乎接受现有的静态资源路径和路由路径(用作/index.html)。

我犯的错误是没有足够仔细地遵循重新路由逻辑。我的代码:

router.route("/*").handler(StaticHandler.create())
router.route().handler({ context: RoutingContext ->
    context.reroute("index.html)
})

将拦截与路由不匹配的所有路径,并将它们重新路由(我不打算进行重定向)到/index.html。但是,重新路由会重新开始整个路由过程,因此我使用/index.html路径返回到全部处理程序,然后再次尝试重新路由(因为静态处理程序只会在以后调用)

因此,解决方案是确保仅重新路由尚未尝试重新路由的路径(并且我可以重新路由到/而不是/index.html):

router.routeWithRegex("\\/.+").handler({ context: RoutingContext ->
    context.reroute("/")
})

和添加Quarkus的静态资源处理程序将负责其余的工作。