You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetty部署Vaadin Fusion访问index.html跳转offline-stub.html报404

问题原因
  • Vaadin Fusion默认开启离线支持特性,当框架检测到前端路由加载失败、网络请求异常时,会自动尝试重定向到/offline-stub.html离线回退页面,你未创建该文件所以触发404错误,同时弹出connection lost提示。
  • 你的index.html缺失路由挂载节点:代码中仅包含<h1>hello</h1>,没有index.ts中路由初始化需要的<div id="outlet"></div>节点,导致路由初始化失败,触发Vaadin的异常回退逻辑。
  • Jetty服务配置错误:
    1. Handler插入顺序错误,insertHandler会将新Handler插入到处理链的前面,你先插入ServletContextHandler再插入ResourceHandler,导致所有请求优先被ResourceHandler处理,需要Servlet处理的Vaadin相关请求无法命中。
    2. 未注册VaadinServlet:Vaadin Fusion需要VaadinServlet处理前端资源自动注入、客户端路由回退、接口请求转发等逻辑,你仅配置了空的ServletContextHandler和原生ResourceHandler,Vaadin的核心服务逻辑没有运行,无法正常加载前端资源。
    3. 未完成前端资源构建:你当前的index.html中仅标注了index.ts会被自动注入,但是你没有执行Vaadin的前端构建命令,实际运行时index.ts没有被引入到页面中,前端逻辑完全未执行。
解决方案
  1. 修复index.html结构,补充路由挂载节点:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Vaadin Grocery App</title>
    <style>
      body {
        margin: 0;
        width: 100vw;
        height: 100vh;
      }

      #outlet {
        height: 100%;
      }
    </style>
    <!-- index.ts is included here automatically (either by the dev server or during the build) -->
  </head>

  <body>
   <div id="outlet"></div>
  </body>
</html>
  1. 处理离线页面问题(二选一即可):
  • 不需要离线支持:在项目的application.properties配置文件中添加配置vaadin.offline.enabled=false,关闭离线回退特性。
  • 需要离线支持:在webapp根目录下创建offline-stub.html文件,添加基础的离线提示内容即可。
  1. 执行前端资源构建:在项目根目录下执行mvn vaadin:build-frontend(Maven项目)或者gradle vaadinBuildFrontend(Gradle项目),完成前端资源打包,自动将index.ts的引用注入到index.html中。

  2. 修正Jetty启动配置,注册VaadinServlet,调整Handler逻辑:

public static void main(String[] args) throws URISyntaxException, IOException {

    Log.setLog(new StdErrLog());
    System.out.println("Server starting...");
    
    String webRootPath = webRoot + "/webapp";
    System.out.println(webRootPath);

    final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    context.setResourceBase(webRootPath);
    
    // 注册VaadinServlet
    ServletHolder vaadinServlet = context.addServlet(com.vaadin.flow.server.VaadinServlet.class, "/*");
    vaadinServlet.setInitParameter("productionMode", "false"); // 开发模式设为false,生产环境设为true
    // 纯前端路由的Fusion项目可删除下面的ui参数配置
    vaadinServlet.setInitParameter("ui", "com.yourpackage.YourEntryUI"); // 替换为你的实际UI类路径

    Server embeddedServer = new Server(8080);
    embeddedServer.setHandler(context); // 直接使用ServletContextHandler处理所有请求,无需单独配置ResourceHandler
    
    try {
        embeddedServer.start();
        embeddedServer.join();
    } catch (Exception e) {
        System.err.println("Server error:\n" + e);
    }
    System.out.println("Server stopped");
}

内容的提问来源于stack exchange,提问作者theMahaloRecords

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:45:07