如何配置嵌入式Tomcat以识别JAR包中的@WebServlet注解
解决嵌入式Tomcat 8.5.28中@WebServlet注解导致的404问题
兄弟,我太懂你踩的这个坑了!嵌入式Tomcat跟咱们平时用的独立部署Tomcat不一样,它默认不会自动扫描并注册带@WebServlet注解的类——你删了手动添加Servlet的代码后,Tomcat根本不知道有这个Servlet存在,自然就返回404了。咱们一步步来搞定,核心就是给addWebapp传对路径,再开启注解扫描的开关。
一、addWebapp该传什么路径?
addWebapp有两个关键参数:第一个是上下文路径(比如传""就对应根路径http://localhost:8080/),第二个是你的Web应用的资源根目录绝对路径,得根据你的项目结构来选:
1. 本地开发环境(Maven/Gradle项目)
如果是本地开发,Servlet类编译后默认会在target/classes(Maven)或build/classes/java/main(Gradle)目录下。直接把这个目录的绝对路径传给addWebapp就行:
Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); // 拿到classes目录的绝对路径 String webappRoot = new File("target/classes").getAbsolutePath(); // 上下文路径设为空串,对应根地址 tomcat.addWebapp("", webappRoot); tomcat.start(); tomcat.getServer().await();
2. 打包成JAR/WAR后的生产环境
如果应用已经打包成可执行JAR,得通过类加载器获取内部资源路径(毕竟JAR里的文件路径和本地目录逻辑不一样):
Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); // 从类加载器获取WEB-INF所在的路径,对应JAR里的WEB-INF/classes ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String webappRoot = classLoader.getResource("WEB-INF").getPath(); tomcat.addWebapp("", webappRoot); tomcat.start(); tomcat.getServer().await();
注意:如果你的JAR里没有显式的WEB-INF目录,得把编译后的class文件放在JAR的WEB-INF/classes路径下,不然Tomcat找不到你的Servlet类。
二、必须补充的注解扫描配置
光传路径还不够,得给Tomcat的Context开启注解扫描功能,不然它还是识别不了@WebServlet:
Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); String webappRoot = new File("target/classes").getAbsolutePath(); Context context = tomcat.addWebapp("", webappRoot); // 设置类加载器,让Tomcat能加载你的Servlet类 context.setClassLoader(Thread.currentThread().getContextClassLoader()); // 配置资源根,指定classes目录的位置 WebResourceRoot resourceRoot = new StandardRoot(context); resourceRoot.addPreResources(new DirResourceSet( resourceRoot, "/WEB-INF/classes", new File("target/classes").getAbsolutePath(), "/" )); context.setResources(resourceRoot); // 添加ContextConfig监听器,开启注解扫描 context.addApplicationListener("org.apache.catalina.startup.ContextConfig"); // 告诉Tomcat不用找web.xml,用注解配置 context.addParameter("org.apache.catalina.startup.ContextConfig.webXml", "");
三、最后检查两个细节
- 你的
@WebServlet注解里的urlPatterns是/hello,那访问地址应该是http://localhost:8080/hello,别多打末尾的斜杠(除非你写的是/hello/*)。 - 启动Tomcat时看日志,有没有出现类似
Scanning for Servlet annotations的日志,有就说明注解扫描已经生效了。
这样配置完,你的HelloServlet就能被Tomcat正确识别,404问题就解决啦!
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

