Embedded Tomcat 10从Fat Jar加载静态资源失败求助
问题原因与解决方案
问题本质
在IDE中运行时,src/main/resources/static是文件系统上的真实目录,因此getResource("static").getFile()能返回有效的文件路径。但打包成Fat Jar后,静态资源位于Jar内部,getFile()返回的是类似file:/tmp/abc/awfemb.jar!/static的URL路径,而Tomcat默认的上下文配置期望一个物理文件目录,导致路径拼接错误,出现资源集无效的问题。
解决方案:使用WebResourceRoot处理Jar内资源
必须通过WebResourceRoot系列类来配置Tomcat的资源加载逻辑,使其能够识别Jar内部的资源。以下是修正后的代码:
import org.apache.catalina.Context; import org.apache.catalina.servlets.DefaultServlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.DirResourceSet; import org.apache.catalina.webresources.JarResourceSet; import org.apache.catalina.webresources.StandardRoot; import java.net.URI; import java.net.URL; public class MainTomcat { public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); tomcat.getConnector(); tomcat.setPort(8080); // 获取static资源的URL(支持文件系统和Jar内两种场景) URL staticUrl = MainTomcat.class.getClassLoader().getResource("static/"); URI staticUri = staticUrl.toURI(); // 创建上下文,不指定docBase(避免Tomcat默认的目录解析逻辑) Context context = tomcat.addContext("/", null); // 配置资源加载根目录 StandardRoot resources = new StandardRoot(context); if (staticUri.getScheme().equals("jar")) { // Jar内资源:使用JarResourceSet加载 resources.addPreResources(new JarResourceSet( resources, "/", // 上下文挂载路径 staticUri, // Jar文件的URI "/" // Jar内的资源路径(static目录下的内容) )); } else { // 文件系统资源(IDE场景):使用DirResourceSet加载 resources.addPreResources(new DirResourceSet( resources, "/", // 上下文挂载路径 staticUri.getPath(), // 文件系统目录路径 "/" // 目录内的资源路径 )); } context.setResources(resources); // 注册并映射DefaultServlet tomcat.addServlet("/", "default", new DefaultServlet()); context.addServletMappingDecoded("/", "default"); tomcat.start(); tomcat.getServer().await(); } }
关键修改说明
- 移除docBase依赖:创建Context时不再传入文件路径,避免Tomcat尝试将Jar URL解析为物理目录。
- 使用WebResourceRoot:通过
StandardRoot统一管理资源加载,根据资源所在位置(文件系统或Jar)选择对应的DirResourceSet或JarResourceSet。 - 兼容两种运行场景:代码自动识别资源的URL协议,同时支持IDE开发和Fat Jar部署。
Maven配置无需修改
你的现有Maven打包配置已经正确,执行mvn clean package后生成的Fat Jar即可正常运行。
内容的提问来源于stack exchange,提问作者DBE
相关产品推荐
相关产品推荐

