router.errorHandler() 未在 Quarkus 中触发

router.errorHandler() not triggered in Quarkus

我正在构建一个带有 React 前端的 Quarkus 应用程序。我对反应还很陌生,目前正在尝试部署我的应用程序。问题是,一旦我构建了我的 React 应用程序并尝试在端口 8080 上使用 Quarkus 为其提供服务,获取“/”路径工作正常但输入“/contact”例如最终出现在 404 错误页面上。我知道互联网上已经有一些解决这个问题的方法,但我发现并尝试过的每一个都没有用。 问题似乎来自我在前端应用程序中使用的 react-router-dom,它不能很好地与 Quarkus 一起使用,如 所示。所以我正在尝试实施之前 post 的“包罗万象”解决方案。 对我来说似乎更有希望的解决方案是 但在我这边,当我收到 404 错误时永远不会触发 errorHandler :

@ApplicationScoped
public class RouterReactFix {

    public void init(@Observes Router router) {
        log.info("Initialized !"); // Triggered
        router.errorHandler(404, rc -> {
            log.info("404"); // Not triggered
            rc.reroute("/");
        });
        router.errorHandler(200, rc -> {
            log.info("200"); // Not triggered, but it isn't an error code so maybe not relevant
        });
        router.get("/my-route").handler(rc -> {log.info("TRIGGERED");}); // Triggered
    }
}

我真的需要你的帮助来使我的反应应用程序工作或找到另一个工作解决方案。 提前谢谢你。

编辑:

我目前的“设置”:

在“AppHandler.tsx”文件中:

<Switch>
  <Route exact path={'/'} component={HomePage} />
  <Route path={'/presentation'} component={PresentationPage} />
  <Route path={'/qanda'} component={QAndAPage} />
  <Route path={'/bots'} component={BotTabHandler} />
  <Route path={'/rules'} component={Rules} />
  <Route path={'/contact'} component={ContactPage} />
</Switch>

浏览我的网站的常用方法是单击嵌入在组件中的按钮,如下所示:

  <Link to={buttonElement.page}> // where buttonElement.page has for example the value '/presentation'

现在,如果我在构建版本(Quarkus 服务器以静态方式提供的版本)中单击页面的按钮(组件),一切正常,浏览器中的 url 变为(例如)localhost:port/presentation 并且我的页面显示正确。 但是,如果在相同的设置上,仍然是构建版本,我在浏览器中手动输入 url "localhost:port/presentation" 我从 Quarkus 收到 404 not found 错误。 当网站仍然由 React 在端口 3000 上提供服务并且其他请求(与服务器相关,例如数据库调用)由 React 在端口 8080 上代理以由 Quarkus 处理时,不会出现此错误(我没有收到 404 错误,当我在浏览器搜索栏中手动输入 URL)

鉴于 Vert.x router 配置不起作用,那么我假设有一个更高级别的组件,该配置正在取代低级组件-级别Vert.x配置。

通常在这些情况下,我猜您正在使用 RESTful 资源提供程序实现,通常是 Resteasy Quarkus.

Resteasy 提供了其他 JAX-RS 兼容的方法来处理映射到 REST 资源的异常,其中 404 未找到 HTTP 资源错误将映射到 javax.ws.rs.NotFoundException 异常。

要处理这种重定向到您的 Web 应用程序根路径的异常,您将实现一个 javax.ws.rs.ext.ExceptionMapper,它可能如下所示:

@Provider
@Priority(Priorities.USER)
public class CustomNotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {

    @Override
    public Response toResponse(NotFoundException e) {
        System.out.println("Handling " + e.getMessage());
        return Response.temporaryRedirect(URI.create("/")).build();
    }
}

请注意,需要添加 @Priority(Priorities.USER) 注释以覆盖默认的 Quarkus 映射器

编辑

如果您想保留 URL 路径,以便客户端框架(在您的情况下为 React / React Router)相应地显示适当的内容,您可以流式传输主 index.html 页面在每个不匹配的请求:

@Provider
@Priority(Priorities.USER)
public class MyNotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {

    @Override
    public Response toResponse(NotFoundException e) {
        final InputStream indexIS = this.getClass().getClassLoader().getResourceAsStream("/META-INF/resources/index.html");
        final InputStreamReader isr = new InputStreamReader(indexIS, StandardCharsets.UTF_8);
        final StringBuilder sb = new StringBuilder();
        int c;
        try {
            while ((c = isr.read()) != -1) {
                sb.append((char) c);
            }
        } catch (IOException ex) {
            return Response.temporaryRedirect(URI.create("/")).build();
        }
        return Response.ok(sb.toString(), MediaType.TEXT_HTML_TYPE).build();
    }
}