SpringBootServletInitializer使用问题:Application非javax.servlet.Servlet
你遇到的核心问题是:SpringBootServletInitializer并不是一个javax.servlet.Servlet实现类,它的作用是作为Spring Boot应用在外部Servlet容器(比如Jetty)中启动的引导器,而非直接作为Servlet处理请求。所以你在override-web.xml里把它配置成servlet-class才会触发这个错误。
1. 修正override-web.xml配置
删掉你手动添加的servlet和servlet-mapping节点,让Spring Boot自动完成Servlet的注册工作。修改后的override-web.xml应该是这样的:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" metadata-complete="false" version="3.1"> <!-- 这里不需要手动配置Servlet,SpringBootServletInitializer会自动引导注册DispatcherServlet --> </web-app>
为什么这样做?因为SpringBootServletInitializer的configure方法会负责初始化Spring应用上下文,并自动注册Spring MVC的DispatcherServlet——它才是真正处理HTTP请求的Servlet实现类。
2. 确保WAR包构建正确(针对Maven项目)
如果你用Maven打包,需要确保pom.xml里的配置符合WAR部署要求:
- 设置打包类型为
war:<packaging>war</packaging> - 排除内嵌的Tomcat依赖(避免和Jetty冲突):
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 添加Servlet API依赖,仅编译时生效 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> </dependencies>
3. 验证Jetty配置
你的bubbleshadow2.xml配置基本没问题,只需要确保jetty.webapps属性指向正确的WAR文件路径,并且Jetty版本(你用的是9.4.9)和Spring Boot版本兼容(Spring Boot 2.x与Jetty 9.x是兼容的)。
额外说明
SpringBootServletInitializer的作用是在外部Servlet容器启动时,通过继承的onStartup方法(来自WebApplicationInitializer)初始化Spring应用上下文,它相当于传统Spring MVC项目中的web.xml或者自定义WebApplicationInitializer实现类,而非直接作为Servlet使用。
按照上面的步骤修改后,重新打包WAR并部署到Jetty,应该就能正常启动了。
内容的提问来源于stack exchange,提问作者Daniel Lynch

