Configure Spring Framework 5.3+, Spring Boot 2.3+ Routing for SPA frontend
Asked Answered
A

2

19

I have a simple frontend application made using Angular. All routings are handled by Angular so I want Spring boot to forward all page traffics to "/" so angular routing can handle them.

There are already some known answers in stackoverflow. They are:

But none of them work anymore because from Spring Framework 5.3 and onwards AntPathMatcher has been replaced with PathPattern. PathPattern is compatible with AntPathMatcher syntax except for the following:

Support for "**" for multi-segment matching is only allowed at the end of a pattern. This helps to eliminate most causes of ambiguity when choosing the closest match for a given request.

So this won't work anymore:

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

So what is the best approach now starting with Spring Framework 5.3?

Do we specify each angular routing and forward them to "/" like below or there are other alternatives?

  @RequestMapping({ "/help/**","/view/**","/admin/**" })
  public String redirectAngularRoutes() {
    return "forward:/";
  }
Amperage answered 17/2, 2022 at 15:7 Comment(4)
I would imagine that you would serve your application in whatever way and just let angular handle any routing within pages of the application. If you serve an app with an actual route in the url I would imagine angular would handle it once it initializes, so it should just be a matter of serving the application to the user. When it comes to api calls they can be to anything (typical REST endpoint calls).Radtke
Still looking for an answer to this :(Devisee
Did you find anything, or did you specify every angular routing? I'm also looking for a solution to this right nowCaresse
no update on this from Spring boot. I specify every routing like the 2nd example in the post. @CaresseAmperage
S
1

You can configure the path matching strategy to use the ant path matcher in your application.yml

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

There is currently no deprecation warning on the Ant Path Matcher but it seems possible it could be removed in the future.

Straw answered 4/4, 2022 at 12:16 Comment(2)
Spring Boot 3.0+ recommend using the PathPatternParser as it provides better performance. So your solution is not applicable . read the spring blog: spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0Amperage
I have the same problem as described in the question, and even though I have set the matching-strategy to be ant_path_matcher it seems it's ignoring/overriding it anywayCaresse
A
0

I found a different approach buried in some obscure part of the internet a little while back but I haven't managed to retrace my steps to give credit where it is due. Apologies to the original author.

In any case, this is the solution that was presented and it seems to be working ok for now.

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)
        }

    }


}

This approach has a downside in that it relies on the client setting the correct header. I've found that when running Cypress tests that wasn't happening correctly and I had to override the cy.visit command like so...

Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
    originalFn(
        url,
        {
            headers: {
                'Sec-Fetch-Mode': 'navigate'
            },
            ...options
        }
    )
})
Amy answered 24/2, 2022 at 23:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.