Spring5 has been around for a long time, and there are some new gameplay elements that we need to uncover.

protected String initLookupPath(HttpServletRequest request) { if (usesPathPatterns()) { request.removeAttribute(UrlPathHelper.PATH_ATTRIBUTE); RequestPath requestPath = ServletRequestPathUtils.getParsedRequestPath(request); String lookupPath = requestPath.pathWithinApplication().value(); return UrlPathHelper.defaultInstance.removeSemicolonContent(lookupPath); } else { return getUrlPathHelper().resolveAndCacheLookupPath(request); }}

This method is available in Spring5, and has not been used before. In the old SpringMVC, when we needed to get the current request address, we got it directly as follows:

String lookupPath = this.getUrlPathHelper().getLookupPathForRequest(request);

This has changed, however, and now retrieves the URL of the current request as follows:

String lookupPath = initLookupPath(request);

In contrast, the initLookupPath method has the usesPathPatterns option, which is new in Spring5, so today Songo has a simple article to share with you what the usesPathPatterns are. How to play!

That’s not a small change! This is especially important if you are using WebFlux in your project!

AntPathMatcher

When we use the @RequestMapping annotation to mark the request interface (or use its equivalent like @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping), We can use some wildcards to match URLs. For a simple example, suppose I have the following five interfaces:

@GetMapping("/hello/**/hello") public String hello() { return "/hello/**/hello"; } @GetMapping("/h? llo") public String hello2() { return "/h? llo"; } @GetMapping("/**/*.html") public String hello3() { return "/**/*.html"; } @GetMapping("/hello/{p1}/{p2}") public String hello4(@PathVariable String p1, @PathVariable String p2) { System.out.println("p1 = " + p1); System.out.println("p2 = " + p2); return "/hello/{p1}/{p2}"; } @GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}") public void handle(@PathVariable String name, @PathVariable String version, @PathVariable String ext) { System.out.println("name = " + name); System.out.println("version = " + version); System.out.println("ext = " + ext); }

Before I explain what interfaces mean, let’s talk about what these wildcards mean:

The wildcard meaning
支那 Matches 0 or more directories
* Matches 0 or more characters
? Matches any single character

Now that we know what wildcards mean, let’s talk about what requests each interface can receive:

  • The first interface can receive things like/hello/123/123/hello,/hello/a/helloAs well as/hello/helloSuch a request, because of the middle支那Represents zero or more directories.
  • The second interface can receive such interfaces as/hallo,/hello,/hMlloNotice that it cannot be received/haalloor/hlloBecause the?Represents a character.
  • The third interface can receive any interface.htmlIs a suffix request, for example/aaa/bb/cc.html,/aa.htmlor/aa/aa.html.
  • The fourth interface, which you’re probably familiar with, and which you’ve probably used in RESTful interface design, accepts requests in a format similar to this/hello/aa/bb, where the parameter p1 corresponds to aa, and the parameter p2 corresponds to bb.
  • The fifth interface uses the regular format. The name, version, and ext parameters are expressed in the regular format. It can accept parameters such as/ spring - web - 3.0.5. JarFormat request, the final parameter name isspring-webThe version is3.0.5, ext.jar.

This is a pre-existing feature in SpringMVC, and it’s always there whether you’ve used it or not.

So who underpins this feature? That’s AntpathMatcher.

AntPathMatcher is a path matcher that implements AntPathMatcher. AntPathMatcher is a path matcher that implements AntPathMatcher. AntPathMatcher is a path matcher that implements AntPathMatcher. This path matching rule comes from the Apache Ant project (https://ant.apache.org), which we don’t really use much anymore. Its replacement is the familiar Maven. If you’re lucky enough to maintain some old projects before 2010, It is possible to come into contact with Ant.

AntPathMatcher is actually used quite extensively in SpringMVC, not only to define interfaces in @RequestMapping, but also in other areas where address matching is involved. For example, when we configure static resource filtering in the SpringMVC configuration file, we also use Ant style path matching:

<mvc:resources mapping="/**" location="/"/>

Ant-style path matching is also used in interceptor path registration, cross-domain path matching, and so on.

Overall, AntPathMatcher is one of Spring’s more primitive path-matching solutions, and while relatively simple, it is inefficient and inconvenient when dealing with URL encoding.

Hence the PathPattern in Spring5.

PathPattern

The PathPattern is designed for Web applications and is mostly similar to the previous AntPathMatcher, with a few minor differences, as I’ll talk about later.

For Servlet applications, the current official recommended URL matching solution is PathPattern (although you can also choose the older AntPathMatcher). But the actual default is still AntPathMatcher; If you are using WebFlux, PathPattern is the only solution.

Note that PathPattern is a very new technique. Currently, the latest version of Spring is 5.3.4. Before Spring5.3, we can only select AntPathMatcher in Servlet applications. Then we can use the PathPattern.

PathPattern preresolves URL rules into PathContainer, which can process URL address matching more quickly. The difference between PathPattern and AntPathMatcher is mainly reflected in two aspects:

First, the PathPattern only supports using ** at the end of the path. If you use ** in the middle of the path, an error will be reported. The first and third interfaces in the previous article will report an error in the PathPattern pattern as follows:

Because using ** in the middle or at the beginning can be confusing, the PathPattern only supports using ** at the end.

Second, PathPattern supports path matching using methods such as {*path}, which can also match multiple paths and assign the matched value to the path variable, such as the following interface:

@GetMapping("/javaboy/{*path}")
public void hello6(@PathVariable String path) {
    System.out.println("path = " + path);
}

If the request path is http://localhost:8080/javaboy/aa, then the parameter value of the path is/aa;

If the request path is http://localhost:8080/javaboy/aa/bb/cc/dd, then the parameter value of the path is/aa/bb/cc/dd.

This is a relatively new way of writing it, because it wasn’t in the AntpathMatcher.

How to use

By default, SpringMVC uses AntPathMatcher, so how do you turn on PathPattern? Simply add the following configuration to the SpringBoot project:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setPatternParser(new PathPatternParser()); }}

After adding this configuration, in the code we posted at the beginning of this article, we go into the if branch and use the PathPattern to parse the request URL.

summary

OK, so much for today’s chat with friends, you can try this thing, but pay attention to choose the version of Spring, be sure to choose the version above 5.3 ~ have a nice weekend