Most of the path matching rules in Spring are based on Ant standards

In fact is not just for SpringMVC, the path of the Spring framework parsing is according to the style of the Ant, concrete implementation in the Spring, for details see org. Springframework. Util. AntPathMatcher, specific rules are as follows

/ * * * {@link PathMatcher} implementation for Ant-style path patterns.
 *
 * <p>Part of this mapping code has been kindly borrowed from <a href="http://ant.apache.org">Apache Ant</a>.
 *
 * <p>The mapping matches URLs using the following rules:<br>
 * <ul>
 * <li>{@code? } matches one character</li> * <li>{@code *} matches zero or more characters</li>
 * <li>{@code **} matches zero or more <em>directories</em> in a path</li>
 * <li>{@code {spring:[a-z]+}} matches the regexp {@code [a-z]+} as a path variable named "spring"</li>
 * </ul>
 *
 * <h3>Examples</h3>
 * <ul>
 * <li>{@codecom/t? st.jsp} &mdash; matches {@code com/test.jsp} but also
 * {@code com/tast.jsp} or {@code com/txst.jsp}</li>
 * <li>{@code com/*.jsp} &mdash; matches all {@code .jsp} files in the
 * {@codecom} directory</li> * <li><code>com/&#42; & # 42; /test.jsp</code> &mdash; matches all {@code test.jsp}
 * files underneath the {@codecom} path</li> * <li><code>org/springframework/&#42; & # 42; /*.jsp</code> &mdash; matches all * {@code .jsp} files underneath the {@codeorg/springframework} path</li> * <li><code>org/&#42; & # 42; /servlet/bla.jsp</code> &mdash; matches * {@code org/springframework/servlet/bla.jsp} but also
 * {@code org/springframework/testing/servlet/bla.jsp} and {@code org/servlet/bla.jsp}</li>
 * <li>{@code com/{filename:\\w+}.jsp} will match {@code com/test.jsp} and assign the value {@code test}
 * to the {@code filename} variable</li>
 * </ul>
 *
 * <p><strong>Note:</strong> a pattern and a path must both be absolute or must
 * both be relative in order for the two to match. Therefore it is recommended
 * that users of this implementation to sanitize patterns in order to prefix
 * them with "/" as it makes sense in the context in which they're used.
 * /
Copy the code

Rules defining standards for symbols

  • ? Matches 1 character
    • Matches 0 or more characters
  • ** Matches 0 or more directories in the path
  • {spring:[a-z]+} assigns the value matched by the regular expression [a-z]+ to the path variable named spring.

It has to be a perfect match, and in SpringMVC only a perfect match goes into the controller layer method

Symbol?

What’s different from the others? It must be a single character and cannot be a slash (/) representing the path separator.

@RequestMapping("/index?" )
@ResponseBody
public String index(a){
    return "index.html";
 }
Copy the code
The results of
Index False 404 error (must contain one character) Index/False 404 error (cannot contain "/") IndexAB False 404 error (cannot contain multiple characters) IndexA True Output page index.htmlCopy the code
The symbol *
  • Although multiple arbitrary characters can be matched, * cannot be used to replace **, because * cannot be a directory or path. That is to say, * is not a substitute for **.
Sample code:
@RequestMapping("/index*")
@ResponseBody
public String index(a){
    return "index.html";
}
Copy the code
Results:
HTML (can be 0 characters) Index/True Output indexa True Output index. HTML (can be 1 character) indexABC true output index Index /a false 404 error ("/a" is a path)Copy the code
The symbol * *

Zero or more directories.** does not itself have to contain a slash

@RequestMapping("/index/**/a")
@ResponseBody
public String index(a){
    return "index.html";
}
Copy the code
Results:
Index /a true Output index.html(can be 0 directories) index/x/a True Output index.html(can be one directory) index/x/z/c/a True Output index.html(can be multiple directories)Copy the code

The symbol {spring: [a-z] +}

{spring:[a-z]+} matches are mostly ignored in other AntPathMatcher articles. I’m going to add something here.

Sample code:

@RequestMapping(“/index/{username:[a-b]+}”) @ResponseBody public String index(@PathVariable(“username”) String username){ System.out.println(username); return username; }

Results:

Index /ab true Displays ab index/abbaaa True Displays ABbaAA index/ A false 404 Error Index/AC false 404 error

Requirement: When PERFORMING RBAC permission verification, I set the administrator access path to /admin/**, hoping that all URI operation addresses starting with /admin/ can be matched.

Manual mode
  • AntPathMatcher can not only match Spring’s @RequestMapping path, but can also be used to match various strings, including file paths and so on.
  • The default path separator of AntPathMatcher is “/”. When matching file paths, note that the path separator is “\” in Windows and “/” in Linux, which is written as follows:
Initialize the create operation

When using AntPathMatcher to create an object, note that AntPathMatcher also has parameter construction. Pass pathSeparator parameter pathSeparator. For file path matching, you need to pass the respective file separator according to different operating systems. This prevents incorrect file path matching.

AntPathMatcher matcher = newAntPathMatcher (File. The separator); AntPathMatcher matcher =new AntPathMatcher(System.getProperty("file.separator"));Copy the code
Perform a match
import org.springframework.util.AntPathMatcher;
String content = "/admin/acuff";
String pattern = "/admin/**";
System.out.println(antPathMatcher.match(pattern, content));
Copy the code
Has more characters

Has more characters, that is, more accurate patterns are preferentially matched. For example, if the URL request /app/dir/file.jsp now has two path matching modes /**/.jsp and /app/dir/.jsp, it will be matched according to the mode /app/dir/*.jsp.

Of course, if this tool is not powerful enough, you can also use RegexRequestMatcher, which supports matching URLS using regular expressions. If you don’t think these are powerful enough, you can rewrite the RequestMatcher interface to customize routing matching rules yourself

Extract the case reference Sample from the Internet
// test exact matching assertTrue(pathMatcher.match("test", "test")); assertTrue(pathMatcher.match("/test", "/test")); assertTrue(pathMatcher.match("http://example.org", "http://example.org")); // SPR-14141 assertFalse(pathMatcher.match("/test.jpg", "test.jpg")); assertFalse(pathMatcher.match("test", "/test")); assertFalse(pathMatcher.match("/test", "test")); // test matching with ? 's assertTrue(pathMatcher.match("t? st", "test")); assertTrue(pathMatcher.match("?? st", "test")); assertTrue(pathMatcher.match("tes?" , "test")); assertTrue(pathMatcher.match("te??" , "test")); assertTrue(pathMatcher.match("? es?" , "test")); assertFalse(pathMatcher.match("tes?" , "tes")); assertFalse(pathMatcher.match("tes?" , "testt")); assertFalse(pathMatcher.match("tes?" , "tsst")); // test matching with *'s assertTrue(pathMatcher.match("*", "test")); assertTrue(pathMatcher.match("test*", "test")); assertTrue(pathMatcher.match("test*", "testTest")); assertTrue(pathMatcher.match("test/*", "test/Test")); assertTrue(pathMatcher.match("test/*", "test/t")); assertTrue(pathMatcher.match("test/*", "test/")); assertTrue(pathMatcher.match("*test*", "AnothertestTest")); assertTrue(pathMatcher.match("*test", "Anothertest")); assertTrue(pathMatcher.match("*.*", "test.")); assertTrue(pathMatcher.match("*.*", "test.test")); assertTrue(pathMatcher.match("*.*", "test.test.test")); assertTrue(pathMatcher.match("test*aaa", "testblaaaa")); assertFalse(pathMatcher.match("test*", "tst")); assertFalse(pathMatcher.match("test*", "tsttest")); assertFalse(pathMatcher.match("test*", "test/")); assertFalse(pathMatcher.match("test*", "test/t")); assertFalse(pathMatcher.match("test/*", "test")); assertFalse(pathMatcher.match("*test*", "tsttst")); assertFalse(pathMatcher.match("*test", "tsttst")); assertFalse(pathMatcher.match("*.*", "tsttst")); assertFalse(pathMatcher.match("test*aaa", "test")); assertFalse(pathMatcher.match("test*aaa", "testblaaab")); // test matching with ? 's and /'s assertTrue(pathMatcher.match("/?" , "/a")); assertTrue(pathMatcher.match("/? /a", "/a/a")); assertTrue(pathMatcher.match("/a/?" , "/a/b")); assertTrue(pathMatcher.match("/?? /a", "/aa/a")); assertTrue(pathMatcher.match("/a/??" , "/a/bb")); assertTrue(pathMatcher.match("/?" , "/a")); // test matching with **'s assertTrue(pathMatcher.match("/**", "/testing/testing")); assertTrue(pathMatcher.match("/*/**", "/testing/testing")); assertTrue(pathMatcher.match("/**/*", "/testing/testing")); assertTrue(pathMatcher.match("/bla/**/bla", "/bla/testing/testing/bla")); assertTrue(pathMatcher.match("/bla/**/bla", "/bla/testing/testing/bla/bla")); assertTrue(pathMatcher.match("/**/test", "/bla/bla/test")); assertTrue(pathMatcher.match("/bla/**/**/bla", "/bla/bla/bla/bla/bla/bla")); assertTrue(pathMatcher.match("/bla*bla/test", "/blaXXXbla/test")); assertTrue(pathMatcher.match("/*bla/test", "/XXXbla/test")); assertFalse(pathMatcher.match("/bla*bla/test", "/blaXXXbl/test")); assertFalse(pathMatcher.match("/*bla/test", "XXXblab/test")); assertFalse(pathMatcher.match("/*bla/test", "XXXbl/test")); assertFalse(pathMatcher.match("/????" , "/bala/bla")); assertFalse(pathMatcher.match("/**/*bla", "/bla/bla/bla/bbb")); assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing/")); assertTrue(pathMatcher.match("/*bla*/**/bla/*", "/XXXblaXXXX/testing/testing/bla/testing")); assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing")); assertTrue(pathMatcher.match("/*bla*/**/bla/**", "/XXXblaXXXX/testing/testing/bla/testing/testing.jpg")); assertTrue(pathMatcher.match("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing/")); assertTrue(pathMatcher.match("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing")); assertTrue(pathMatcher.match("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing")); assertFalse(pathMatcher.match("*bla*/**/bla/*", "XXXblaXXXX/testing/testing/bla/testing/testing")); assertFalse(pathMatcher.match("/x/x/**/bla", "/x/x/x/")); assertTrue(pathMatcher.match("/foo/bar/**", "/foo/bar")) ; assertTrue(pathMatcher.match("", "")); assertTrue(pathMatcher.match("/{bla}.*", "/testing.html"));Copy the code

Spring MVC URL address matching utility class

AntPathRequestMatcher

//.jsp, /app//dir/file., /**/example, /app/.x syntax like this is often used in Spring MVC. The utility class that is responsible for really determining whether a match is made is AntPathRequestMatcher