map all requests instead of specific pattern in Spring Boot

I don't know spring specifically, so I'm just making my best guess based on experience with other frameworks.

First, shouldn't the pattern exclude the forward slash, since you are already including it in your path?

/{path:^(?!rest/).*}

If that doesn't work, then all I can think is that the AntPathMatcher doesn't support lookaheads.

The typical pattern for this design would be to implement both the /rest/* and /* routes. In some frameworks this is just about ordering them correctly. According to Spring MVC's documentation, you may need to play around with the rules to make the /rest/* route "more specific".

Here are the rules:

When multiple patterns match a URL, they must be compared to find the best match. This done via AntPathMatcher.getPatternComparator(String path) which looks for patterns that more specific.

A pattern is less specific if it has a lower count of URI variables and single wildcards counted as 1 and double wildcards counted as 2. Given an equal score, the longer pattern is chosen. Given the same score and length, the pattern with more URI variables than wildcards is chosen.

The default mapping pattern /** is excluded from scoring and always sorted last. Also prefix patterns such as /public/** are considered less specific than other pattern that don’t have double wildcards.

For the full details see AntPatternComparator in AntPathMatcher and also keep mind that the PathMatcher implementation used can be customized. See Path Matching in the configuration section.

So, based on my interpretation of those rules and your code, I think something along these lines would work:

// Your more specific patterns will take precedence
@RequestMapping(value = "/rest/**")
    public String handleRestRequests() {
        // forward this to your rest services
    }
}

// Your less specific patterns will only apply if the more specific ones don't match
@RequestMapping(value = "/**")
    public String forwardRequests() {
        // Everything else
        return "forward:/";
    }
}

Well, as @JDB said, the AntPathMatcher compares the paths and finds the best match. So you don't have to be worry about the endpoints, which have specified paths, like my /rest api.

You can add this:

@RequestMapping(value = "/{path:[^\\.]*}")
public String redirect() {
  return "forward:/";
}

and all of your requests, eg. /login, will be forwarded correctly to index.html, where javascript can handle it.

The problem is with the URLs like /project/edit/33. They doesn't match this regular expression, so you will see the Whitelabel Error Page 404 Not Found. You can write this:

@RequestMapping(value = "/**/{path:[^\\.]*}")
public String redirect() {
  return "forward:/";
}

and it works fine, but if you have security enabled, the /ouath/token will return:

{  
   "timestamp":"2018-02-05T09:13:28.104+0000",
   "status":405,
   "error":"Method Not Allowed",
   "exception":"org.springframework.web.HttpRequestMethodNotSupportedException",
   "message":"Request method 'POST' not supported",
   "path":"/oauth/token"
}

so you have to exclude oauth urls:

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

and it works fine.

If you have problems with other endpointes provided by the framework, like /health you can change regular expression to /**/{path:^(?!oauth|health).*}/{path:[^\\.]*}

It looks awfull, but it works. I belive someone will post here a better and cleaner solution.