从原生Spring MVC迁移到Spring Boot:目录索引请求处理问题
解决方案
方法1:自定义全局控制器处理未匹配请求
创建全局控制器,捕获所有未被业务接口处理的GET请求,自动检查目标路径下是否存在index.jsp,存在则转发至该页面:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import jakarta.servlet.ServletContext; @Controller @RequestMapping("/**") public class DirectoryIndexController { private final ServletContext servletContext; public DirectoryIndexController(ServletContext servletContext) { this.servletContext = servletContext; } @GetMapping public String handleDirectoryIndex(@PathVariable(required = false) String path) { String targetPath = (path == null) ? "/" : "/" + path; String indexPath = targetPath + "/index.jsp"; if (servletContext.getResource(indexPath) != null) { return "forward:" + indexPath; } return "forward:/error"; } }
该控制器优先级低于业务接口,不会影响已有请求逻辑。
方法2:手动注册视图控制器(适合少量目录)
若目录数量有限,可通过WebMvcConfigurer手动配置每个目录的转发规则:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/test1").setViewName("forward:/test1/index.jsp"); registry.addViewController("/test1/").setViewName("forward:/test1/index.jsp"); registry.addViewController("/test2").setViewName("forward:/test2/index.jsp"); registry.addViewController("/test2/").setViewName("forward:/test2/index.jsp"); // 其他目录按此格式添加 } }
方法3:扩展请求映射处理器(动态批量匹配)
通过扩展RequestMappingHandlerMapping,实现请求匹配失败时自动检查目录下的index.jsp,无需手动配置每个目录:
1. 自定义请求映射处理器
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; public class DirectoryIndexRequestMappingHandlerMapping extends RequestMappingHandlerMapping { private final ServletContext servletContext; public DirectoryIndexRequestMappingHandlerMapping(ServletContext servletContext) { this.servletContext = servletContext; } @Override protected Object handleNoMatch(Object handler, String lookupPath, HttpServletRequest request) throws IOException { String indexPath = lookupPath + "/index.jsp"; if (servletContext.getResource(indexPath) != null) { request.getRequestDispatcher(indexPath).forward(request, request.getResponse()); return null; } return super.handleNoMatch(handler, lookupPath, request); } }
2. 注册自定义处理器
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import jakarta.servlet.ServletContext; @Configuration public class WebMvcConfig { @Bean public RequestMappingHandlerMapping requestMappingHandlerMapping(ServletContext servletContext) { return new DirectoryIndexRequestMappingHandlerMapping(servletContext); } }
关键配置确认
确保application.properties中的视图解析配置正确:
spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp
内容的提问来源于stack exchange,提问作者Jakub Królikowski
相关产品推荐
相关产品推荐

