Spring Boot 3.0.0迁移报错:缺失doFilterInternal方法实现
问题
将应用从Java 11 Spring Boot 2.7.0迁移至Java 17 Spring Boot 3.0.0后,调用REST API时触发java.lang.AbstractMethodError错误,提示抽象类org.springframework.web.filter.OncePerRequestFilter的抽象方法doFilterInternal(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse, jakarta.servlet.FilterChain)缺失实现,错误日志如下:
2022-12-15T10:06:21.542 INFO [http-nio-8200-exec-1 ] o.a.c.c.C.[.[.[/] line: 173 : Initializing Spring DispatcherServlet 'dispatcherServlet' 2022-12-15T10:06:21.542 INFO [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 525 : Initializing Servlet 'dispatcherServlet' 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 527 : Detected StandardServletMultipartResolver 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 551 : Detected AcceptHeaderLocaleResolver 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 577 : Detected FixedThemeResolver 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 727 : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@6de84336 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 791 : Detected org.springframework.web.servlet.support.SessionFlashMapManager@1d637673 2022-12-15T10:06:21.542 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 542 : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 2022-12-15T10:06:21.542 INFO [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 547 : Completed initialization in 0 ms 2022-12-15T10:06:21.589 ERROR [http-nio-8200-exec-1 ] o.a.c.c.C.[.[.[.[dispatcherServlet] line: 175 : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Filter execution threw an exception] with root cause java.lang.AbstractMethodError: Missing implementation of resolved method 'abstract void doFilterInternal(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse, jakarta.servlet.FilterChain)' of abstract class org.springframework.web.filter.OncePerRequestFilter. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.2.jar:6.0.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.2.jar:6.0.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) ~[spring-web-6.0.2.jar:6.0.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.2.jar:6.0.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.1.jar:10.1.1] at java.lang.Thread.run(Thread.java:833) ~[?:?] 2022-12-15T10:06:21.623 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line: 119 : "ERROR" dispatch for GET "/error", parameters={} 2022-12-15T10:06:21.639 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.m.m.a.RequestMappingHandlerMapping line: 527 : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 2022-12-15T10:06:21.701 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.v.ContentNegotiatingViewResolver line: 354 : Selected 'text/html' given [text/html, text/html;q=0.8] 2022-12-15T10:06:21.717 DEBUG [http-nio-8200-exec-1 ] o.s.w.s.DispatcherServlet line:1124 : Exiting from "ERROR" dispatch, status 500 2022-12-15T10:06:21.839 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.DispatcherServlet line: 119 : GET "/favicon.ico", parameters={} 2022-12-15T10:06:21.839 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.h.SimpleUrlHandlerMapping line: 527 : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]] 2022-12-15T10:06:21.854 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.r.ResourceHttpRequestHandler line: 557 : Resource not found 2022-12-15T10:06:21.854 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.DispatcherServlet line:1128 : Completed 404 NOT_FOUND 2022-12-15T10:06:21.870 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.DispatcherServlet line: 119 : "ERROR" dispatch for GET "/error", parameters={} 2022-12-15T10:06:21.870 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.m.m.a.RequestMappingHandlerMapping line: 527 : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2022-12-15T10:06:21.901 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.m.m.a.HttpEntityMethodProcessor line: 275 : Using 'application/json', given [image/avif, image/webp, */*] and supported [application/json, application/*+json] 2022-12-15T10:06:21.903 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.m.m.a.HttpEntityMethodProcessor line: 119 : Writing [{timestamp=Thu Dec 15 10:06:21 CET 2022, status=404, error=Not Found, path=/favicon.ico}] 2022-12-15T10:06:21.923 DEBUG [http-nio-8200-exec-2 ] o.s.w.s.DispatcherServlet line:1124 : Exiting from "ERROR" dispatch, status 404 Disconnected from the target VM, address: '127.0.0.1:53855', transport: 'socket' 2022-12-15T10:07:41.497 INFO [SpringApplicationShutdownHook] o.s.b.w.e.t.GracefulShutdown line: 53 : Commencing graceful shutdown. Waiting for active requests to complete 2022-12-15T10:07:41.505 INFO [tomcat-shutdown ] o.s.b.w.e.t.GracefulShutdown line: 78 : Graceful shutdown complete Process finished with exit code 130
解决方案
原因分析
Spring Boot 3.x全面切换到Jakarta EE API(原Java EE),OncePerRequestFilter的doFilterInternal方法参数已从javax.servlet包下的类替换为jakarta.servlet包下的对应类。如果项目中自定义Filter仍使用旧的javax.servlet包类实现该方法,就会出现此错误。
解决步骤
- 替换自定义Filter的导入包:将所有
import javax.servlet.*及相关子包导入替换为import jakarta.servlet.* - 修正
doFilterInternal方法签名:确保方法参数类型为jakarta.servlet.http.HttpServletRequest、jakarta.servlet.http.HttpServletResponse和jakarta.servlet.FilterChain - 清理依赖:检查项目依赖树,排除任何残留的
javax.servlet相关依赖,Spring Boot 3.x默认已引入Jakarta版本的Servlet API,无需额外添加 - 重新编译并运行项目,验证错误是否消除
内容的提问来源于stack exchange,提问作者Иван Ристић Л
相关产品推荐
相关产品推荐

