为 SPA 前端配置 Spring Framework 5.3+、Spring Boot 2.3+ 路由

Imt*_*que 18 spring routes single-page-application spring-boot angular

我有一个使用 Angular 制作的简单前端应用程序。所有路由均由 Angular 处理,因此我希望 Spring boot 将所有页面流量转发到,"/"以便 Angular 路由可以处理它们。

stackoverflow 中已经有一些已知的答案。他们是:

但它们都不再工作了,因为从Spring Framework 5.3 及更高版本开始,它们 AntPathMatcher已被PathPattern. PathPattern与语法兼容,AntPathMatcher但以下内容除外:

仅允许在模式末尾支持多段匹配的“**”。在为给定请求选择最接近的匹配时,这有助于消除大多数歧义原因。

所以这不再起作用:

  // Match everything without a suffix (so not a static resource)
  @RequestMapping(value = "/**/{path:[^.]*}")
  public String redirectAngularRoutes() {
    return "forward:/";
  }
Run Code Online (Sandbox Code Playgroud)

那么从 Spring Framework 5.3 开始,最好的方法是什么?

我们是否指定每个角度路由及其forward如下所示"/",或者还有其他替代方案?

  @RequestMapping({ "/help/**","/view/**","/admin/**" })
  public String redirectAngularRoutes() {
    return "forward:/";
  }
Run Code Online (Sandbox Code Playgroud)

Kev*_*dge 0

不久前,我在互联网的某个不起眼的地方发现了一种不同的方法,但我还没有设法回溯我的步骤来给予应有的信任。向原作者致歉。

无论如何,这就是所提出的解决方案,目前似乎运行良好。

import org.springframework.web.filter.OncePerRequestFilter
import javax.servlet.FilterChain
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse


class AngularRoutingFilter : OncePerRequestFilter() {


    override fun doFilterInternal(
            request: HttpServletRequest,
            response: HttpServletResponse,
            filterChain: FilterChain
    ) {

        val mode = request.getHeader("Sec-Fetch-Mode")

        when (mode) {
            "navigate" -> {
                val rd = request.getRequestDispatcher("/")
                rd.forward(request, response)
            }
            else -> filterChain.doFilter(request, response)
        }

    }


}
Run Code Online (Sandbox Code Playgroud)

这种方法有一个缺点,因为它依赖于客户端设置正确的标头。我发现在运行赛普拉斯测试时,没有正确发生,我必须像这样覆盖 cy.visit 命令......

Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
    originalFn(
        url,
        {
            headers: {
                'Sec-Fetch-Mode': 'navigate'
            },
            ...options
        }
    )
})
Run Code Online (Sandbox Code Playgroud)