Spring 6.0.11中DefaultHandler创建及配置问题求助
Spring MVC默认处理器配置与文档指引疑问
问题说明
参考Spring 3.2版本MVC文档的17.4章节,了解到RequestMappingHandlerMapping是默认配置的组件,可通过设置defaultHandler属性处理所有未被指定处理器映射的请求。但翻遍整个MVC文档(包括处理器映射未自动配置的旧版内容),仍无法明确如何创建符合要求的默认处理器类。同时疑惑这类基础配置的官方指引该如何查找,难道只能依赖经验传递?
当前代码与报错信息
1. Servlet配置类
package com.sp.config; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.view.InternalResourceViewResolver; import com.sp.controllers.MainController; @Configuration @EnableWebMvc @ComponentScan(basePackages = {"com.sp"}) public class ServicePlatformConfig { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/view/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean public JdbcTemplate jdbcTemplate() { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUsername(""); dataSource.setPassword(""); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/service_platform?useSSL=false"); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); return dataSource; } @Autowired public MainController mainController; @Bean public RequestMappingHandlerMapping handlerMapping() { RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping(); handlerMapping.setDefaultHandler(mainController); return handlerMapping; } @Bean public RequestMappingHandlerAdapter handlerMappingAdapter() { RequestMappingHandlerAdapter handlerMappingAdapter = new RequestMappingHandlerAdapter(); MainController mc = new MainController(); List al = new ArrayList(); al.add(mc); handlerMappingAdapter.setReturnValueHandlers(al); return handlerMappingAdapter; } }
2. 主控制器代码
@Controller public class MainController { @Autowired private TicketDAO TicketDAO; @RequestMapping(value="/", method = RequestMethod.GET) public String showHomepage(Model model) { List<Ticket> ticketList = TicketDAO.loadTickets(); model.addAttribute("tickets", ticketList); for(Ticket ticket : ticketList) { System.out.println(":0 keep going"); System.out.println(ticket); } return "ticket-list"; } @ResponseBody @RequestMapping public String error() { System.out.println("test test test"); return "test test test"; } }
3. 访问未映射链接的报错日志
org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/service-platform] threw exception [No adapter for handler [com.sp.controllers.MainController@72473f59]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler] with root cause jakarta.servlet.ServletException: No adapter for handler [com.sp.controllers.MainController@72473f59]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1316) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:676) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:1589)
解决方案
一、修复默认处理器配置错误
报错核心原因:直接将@Controller类作为defaultHandler传入,且手动配置的RequestMappingHandlerAdapter错误地把控制器实例当成了ReturnValueHandler,破坏了@EnableWebMvc自动配置的适配逻辑。
修正步骤:
- 删除自定义的
handlerMappingAdapterBean:@EnableWebMvc已经自动配置了符合要求的RequestMappingHandlerAdapter,手动配置会覆盖默认逻辑导致适配失败。 - 选择合适的默认处理器实现方式:
- 方式一(推荐):利用
@RequestMapping的路径匹配特性,直接在控制器中写一个匹配所有路径的方法,Spring会自动将其作为未匹配请求的 fallback:@Controller public class MainController { // 原有方法保留 @ResponseBody @RequestMapping(value = "**", method = {RequestMethod.GET, RequestMethod.POST}) public String error() { System.out.println("test test test"); return "test test test"; } } - 方式二(若坚持用
setDefaultHandler):将控制器中的具体方法包装为HandlerMethod传入,而非整个控制器实例:@Bean public RequestMappingHandlerMapping handlerMapping() throws NoSuchMethodException { RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping(); handlerMapping.setDefaultHandler(new HandlerMethod(mainController, MainController.class.getMethod("error"))); return handlerMapping; }
- 方式一(推荐):利用
二、官方文档查找指引
- 优先查API文档:针对
RequestMappingHandlerMapping的setDefaultHandler方法,直接查看对应版本的Javadoc,会明确参数支持的类型(如HandlerMethod、Controller接口实现类、HttpRequestHandler等)。 - 定位文档核心章节:在对应版本的Spring MVC参考文档中,搜索「Handler Mapping」或「Default Handler」,在「Web MVC Framework」→「Handler Mappings」或「Advanced Configuration」章节中,能找到自定义处理器映射属性的细节说明。
- 匹配文档版本:确保使用的文档版本与项目依赖的Spring版本一致,Spring官网提供了完整的文档归档,可直接找到对应版本的参考内容。
内容的提问来源于stack exchange,提问作者bschwarz67
相关产品推荐
相关产品推荐

