Spring Boot SPA URL Rewrite



我正在尝试构建一个SPA后端(静态内容服务器,api(,其中包含一些需要灵活URL重写/路由/处理的附加功能/控件。事实证明,这些要求很难一起实现,尽管我在这里阅读了一些类似的答案中尝试了这种方法。

我需要做什么:

  1. 从URL路径提供静态资产(js,images,css,html等(:/assets/
  2. 将这些静态资产存储在文件系统目录中并映射到上述路径
  3. 对于未找到的任何静态资产请求,返回 404
  4. 从一组命名的 URL 路径公开 REST API:/api/和/otherapi/等...
  5. 对于这些 URL 路径之外的所有其他请求,请提供/index.htm 以引导 SPA

到目前为止,我有以下几点...

对于 REST API:

@RestController
@RequestMapping(value="/api/**")
public class StateAPIController {
@RequestMapping(value = {"/api/method1"}, method = RequestMethod.POST)
@ResponseBody
public String method1() {
return "method1...";
}
@RequestMapping(value = {"/api/method2"}, method = RequestMethod.POST)
@ResponseBody
public String method2() {
return "method2...";
}
}

(这工作正常(

要从特定文件系统位置呈现静态文件并将"/"映射到"/index.htm":

@Configuration
@EnableWebMvc
public class AssetServerConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/")
.addResourceLocations("file:/some/path/index.htm");
registry
.addResourceHandler("/assets/**")
.addResourceLocations("file:/some/path/assets/");
}
@Bean
public ViewResolver viewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(InternalResourceView.class);
return viewResolver;
}

}

(这有效,但不确定是否是解决此问题的最佳方法(

要将任何其他请求(在这些保留路径之外(重定向/转发到"/"(因此是"/index.htm"(:

@ControllerAdvice
@RequestMapping(value="/**")
public class AssetServerController {
@RequestMapping(value = {"/**/{path:[^\.]*}", "/{path:^(?!/assets/).*}", "/{path:^(?!/api/).*}"}, method = RequestMethod.GET)
public String index() {
return "forward:/";
}
}

(这只能部分工作...以及我需要帮助的主要问题(

所以,在这里,我需要排除一个路径列表(/assets/&/api/(,但事实证明,这很难在 RequestMap 中使用正则表达式/AntPathMatcher 过滤器,并且既有错误匹配(在不应该的时候显示索引.htm又有未命中(当它应该显示索引时显示 404.htm(。

由于上述原因,当其中一个保留路径(例如资产(下缺少资源时,我也无法正确提供 404。

a( 解决这个问题的最佳方法是什么? 我完全错了吗?有没有更好的方法?

b( 我如何使正则表达式工作,因为它似乎不遵循正常的正则表达式规则,而且到目前为止我看到的示例没有实现我的目标......

在这里回答:Spring RequestMapping Regex 以排除字符串

基于这里的答案:春季@RequestMapping"不包含"正则表达式

用于排除/assets/的模式:value = {"/{path:(?!.*assets).+}/**"}

最新更新