嵌入式Tomcat 8无web.xml时@WebServlet注解失效无法访问资源
解决方案
根因
嵌入式Tomcat默认未开启Servlet3.0+注解扫描,且未将项目编译后的类路径纳入资源扫描范围,导致@WebServlet注解无法被识别,同时资源配置不全导致jsp访问失败。
第一步:调整pom.xml依赖
统一Tomcat组件版本,避免依赖冲突,同时调整servlet-api作用域:
<properties> <tomcat.version>8.5.23</tomcat.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>14</java.version> </properties> <dependencies> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.eclipse.jdt.core.compiler</groupId> <artifactId>ecj</artifactId> <version>4.6.1</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies>
第二步:修改App.java启动配置
新增注解扫描支持、添加编译类路径到Tomcat资源目录:
import org.apache.catalina.LifecycleException; import org.apache.catalina.StandardServer; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.DirResourceSet; import org.apache.catalina.webresources.StandardRoot; import org.apache.catalina.core.AprLifecycleListener; import java.io.File; public class App { public static void main(String[] args) throws LifecycleException { int port = 8085; Tomcat tomcat = new Tomcat(); tomcat.setPort(port); StandardServer server = (StandardServer) tomcat.getServer(); AprLifecycleListener listener = new AprLifecycleListener(); server.addLifecycleListener(listener); String docBase = new File("src/main/webapp").getAbsolutePath(); StandardContext context = (StandardContext) tomcat.addWebapp("/Servlet_Basic", docBase); // 关闭metadata-complete,开启注解扫描 context.setMetadataComplete(false); // 明确Servlet版本为3.1,支持@WebServlet注解 context.getServletContext().setEffectiveMajorVersion(3); context.getServletContext().setEffectiveMinorVersion(1); // 添加编译后的类路径到Tomcat资源目录,让Tomcat能扫描到自定义Servlet File classesDir = new File("target/classes"); WebResourceRoot resources = new StandardRoot(context); resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", classesDir.getAbsolutePath(), "/")); context.setResources(resources); tomcat.start(); System.out.println("Tomcat server started at port " + port); tomcat.getServer().await(); } }
第三步:运行验证
- 启动项目前先执行
mvn compile,确保编译后的class文件生成在target/classes目录下 - 启动App类,访问以下地址即可正常响应:
- http://localhost:8085/Servlet_Basic/index.jsp :返回Hello World页面
- http://localhost:8085/Servlet_Basic/hello :返回Servlet定义的页面内容
内容的提问来源于stack exchange,提问作者kverma28
相关产品推荐
相关产品推荐

