Spring request mapping regex with deeper paths

93 Views Asked by At

How do I use regex to match the following examples in a Spring @RequestMapping:

  1. localhost:8080
  2. localhost:8080/settings
  3. localhost:8080/settings/users
  4. localhost:8080/settings/users/roles
  5. localhost:8080/settings/users/roles/admin

While not allowing these ones:

  1. localhost:8080/style.css
  2. localhost:8080/manifest.json
  3. localhost:8080/api
  4. localhost:8080/api/users
  5. localhost:8080/api/users/abc

I have this regex /{path:[^\\.]*} that seems to only concentrate on not matching URLs with a dot ".". Also, 3., 4., and 5. do not work.

I can change the regex to /{path:[^\\.]*}/* and then 3. does work, but 2. will not work anymore.

What regex must be used to match the above URI (without localhost:8080) of the URLs?

I use it for this FrontendController.java:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class FrontendController {
    private static final Logger logger = LoggerFactory.getLogger(FrontendController.class);

    @RequestMapping(value = "/{path:[^\\.]*}/*")
    public String redirect() {
        logger.info("Redirect call to the frontend");
        return "forward:/";
    }
}
3

There are 3 best solutions below

3
On BEST ANSWER

You can accomplish this with the following pattern:

^localhost:8080(?!\/api)(?:\/\w+)*$

Explanation for (?!\/api)(?:\/\w+)*:

-(?!\/api) is negative lookahead, ensuring that this point in the pattern isn't immediately followed by /api.

-(?: ) is a non-capturing group, so the pattern it contains can be quantified with * as a group.

-\w+ is one or more word characters ([a-zA-Z0-9_])

https://regex101.com/r/VMf2zE/1

0
On

This works for the examples you've given:

^(/settings.*)?$

See live demo.

0
On

Try this:

^localhost:8080(?!.+\.[^./]+$)(?!/api(?:$|/))(?:.+)?$

See at https://regex101.com/r/Gbogga/latest

Explaination:

^localhost:8080 matches literally in the start of string.

(?!.+\.[^./]+$) ensures that the path does not lead to a file.

(?!/api(?:$|/)) ensures that it does not lead to api path.

(?:.+)? optionally matches path bejont localhost:8080