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服务配置错误:
- Handler插入顺序错误,
insertHandler会将新Handler插入到处理链的前面,你先插入ServletContextHandler再插入ResourceHandler,导致所有请求优先被ResourceHandler处理,需要Servlet处理的Vaadin相关请求无法命中。 - 未注册VaadinServlet:Vaadin Fusion需要VaadinServlet处理前端资源自动注入、客户端路由回退、接口请求转发等逻辑,你仅配置了空的ServletContextHandler和原生ResourceHandler,Vaadin的核心服务逻辑没有运行,无法正常加载前端资源。
- 未完成前端资源构建:你当前的
index.html中仅标注了index.ts会被自动注入,但是你没有执行Vaadin的前端构建命令,实际运行时index.ts没有被引入到页面中,前端逻辑完全未执行。
- Handler插入顺序错误,
解决方案
- 修复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>
- 处理离线页面问题(二选一即可):
- 不需要离线支持:在项目的
application.properties配置文件中添加配置vaadin.offline.enabled=false,关闭离线回退特性。 - 需要离线支持:在webapp根目录下创建
offline-stub.html文件,添加基础的离线提示内容即可。
执行前端资源构建:在项目根目录下执行
mvn vaadin:build-frontend(Maven项目)或者gradle vaadinBuildFrontend(Gradle项目),完成前端资源打包,自动将index.ts的引用注入到index.html中。修正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
相关产品推荐
相关产品推荐

