Spring Boot配置Vue路由接管非/rest/**请求失败排查
问题分析与解决方案
你遇到的问题核心是Spring路径匹配的规则和你写的正则表达式不匹配,导致转发逻辑没有正确排除/rest/**开头的请求。我来拆解下问题出在哪,再给你几个靠谱的解决方案:
为什么你的配置不生效?
你写的正则^(?!/rest/).*在Spring的@RequestMapping路径变量里逻辑是错的:
- Spring中
/{path:xxx}里的path变量,匹配的是第一个/之后的路径内容(比如请求/rest/project/1,path的值是rest/project/1,而非/rest/project/1)。 - 你的负向预查
(?!/rest/)永远为真,因为path里根本没有开头的/,导致这个路由会匹配所有请求(包括/rest/**),进而把REST接口的请求也转发到/,和你的RestController冲突,自然达不到预期效果。
解决方案一:修正Controller的正则匹配
直接修改MainController的路径匹配规则,让它正确排除/rest开头的请求,同时覆盖根路径:
@Controller public class MainController { // 处理根路径请求 @RequestMapping("/") public String root() { return "forward:/index.html"; } // 匹配所有非/rest开头的路径(GET/POST都兼容) @RequestMapping(value = "/{path:^(?!rest).*}", method = {RequestMethod.GET, RequestMethod.POST}) public String forwardRequests() { return "forward:/index.html"; } }
这里的正则^(?!rest).*表示:路径段的开头不是rest,这样所有/rest/**的请求都会被排除,不会进入转发逻辑。
解决方案二:用WebMvcConfigurer配置更优雅的转发(推荐)
这种方式更灵活,还能兼顾静态资源的访问(比如Vue打包后的js、css文件),避免出现静态资源无法加载的问题:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/") .resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { Resource requestedResource = location.createRelative(resourcePath); // 如果请求的资源不存在(比如是Vue路由路径),就返回index.html让Vue处理 return requestedResource.exists() && requestedResource.isReadable() ? requestedResource : location.createRelative("index.html"); } }); } }
这个逻辑的好处是:
- 优先处理真实存在的静态资源(比如
/js/app.js),不会被转发; - 只有当请求的资源不存在时(比如Vue的路由路径
/dashboard),才返回index.html让Vue Router接管; @RestController的/rest/**接口因为RequestMapping优先级更高,会被正常处理,不会被转发。
额外注意点
确保你的Vue项目打包后的文件(dist目录下的所有内容),已经放到Spring Boot项目的src/main/resources/static目录下,这样Spring才能正确访问到静态资源。
内容的提问来源于stack exchange,提问作者kojot
相关产品推荐
相关产品推荐

