Spring MVC 6设置默认处理器后访问未映射URL报错求助
问题分析与解决方案
错误原因
你遇到的No adapter for handler错误,核心问题有三个:
- 直接
new ErrorController()创建的实例未被Spring容器管理,无法被Spring MVC的注解处理器识别。 handlerMapping.setDefaultHandler("errorController")传入的是字符串Bean名称,但该方法需要的是实际的Handler实例,不是名称。- 即使传入正确的Controller实例,
RequestMappingHandlerMapping会把整个Controller对象当作Handler,而Spring MVC的RequestMappingHandlerAdapter只处理带有@RequestMapping注解的方法,不直接处理Controller实例,因此找不到适配的处理器适配器。
正确实现方式
方式一:用SimpleUrlHandlerMapping映射所有未匹配URL到ErrorController的方法
这是最贴合需求的方式,直接把所有未显式映射的URL路由到ErrorController的error()方法:
@Configuration public class WebConfig { // 注入Spring容器管理的ErrorController实例 @Autowired private ErrorController errorController; @Bean public SimpleUrlHandlerMapping defaultHandlerMapping() { SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); // 设置最高优先级,确保先于其他HandlerMapping执行 mapping.setOrder(Integer.MIN_VALUE); Map<String, Object> urlMap = new HashMap<>(); // 用HandlerMethod包装Controller的具体方法 urlMap.put("/**", new HandlerMethod(errorController, "error")); mapping.setUrlMap(urlMap); return mapping; } }
方式二:让ErrorController实现HttpRequestHandler接口
通过实现Spring MVC原生的HttpRequestHandler接口,让Controller实例可以直接被HttpRequestHandlerAdapter适配,从而作为默认处理器:
修改ErrorController:
package com.sp.controllers; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.HttpRequestHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.io.IOException; @Controller @RequestMapping(value="/error") public class ErrorController implements HttpRequestHandler { @ResponseBody @GetMapping public String error() { System.out.println("test test test"); return "test test test"; } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 复用已有的error方法逻辑 String result = error(); response.setContentType("text/plain;charset=UTF-8"); response.getWriter().write(result); } }
修改配置类的HandlerMapping:
@Bean public RequestMappingHandlerMapping handlerMapping(ErrorController errorController) { RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping(); // 注入Spring容器中的ErrorController实例作为默认处理器 handlerMapping.setDefaultHandler(errorController); return handlerMapping; }
额外说明
如果只是想处理404错误,Spring MVC还提供了更简便的原生方案:可以创建一个带有@RequestMapping("error/404")的方法,并在配置类中通过WebMvcConfigurer配置errorPage(),不过这和你用defaultHandler的需求略有不同,根据实际场景选择即可。
内容的提问来源于stack exchange,提问作者bschwarz67
相关产品推荐
相关产品推荐

