当前位置: 首页 > 科技观察

SpringBoot请求路径可以定义为------格式吗?

时间:2023-03-13 19:49:06 科技观察

前两天宋哥给大家分享了如何在SpringSecurity中实现权限通配符的功能,其中使用了一个“迂回的方式”AntPathMatcher。有朋友对此不熟悉,问宋哥能不能单独介绍一下这个东西。好的,安排!然而,AntPathMatcher实际上正在逐渐过时。它的替代品是PathPattern。我把这两个放在一起分享给大家。Spring5也出来很久了,还有一些新的玩法需要我们慢慢去发掘。其中,系统解析当前请求路径的方法位于:org.springframework.web.servlet.handler.AbstractHandlerMapping#initLookupPath:protectedStringinitLookupPath(HttpServletRequestrequest){if(usesPathPatterns()){request.removeAttribute(UrlPathHelper.PATH_ATTRIBUTE);RequestPathrequestPath=ServletRequestPathUtils.getParsedRequestPath(请求);StringlookupPath=requestPath.pathWithinApplication().value();返回UrlPathHelper.defaultInstance。removeSemicolonContent(lookupPath);}else{returngetUrlPathHelper().resolveAndCacheLookupPath(request);}}这个方法是Spring5出来的,之前没有这个方法。在旧的SpringMVC中,当我们需要获取当前请求地址时,可以直接通过以下方法获取:StringlookupPath=this.getUrlPathHelper().getLookupPathForRequest(request);但是现在变了,现在我们获取当前请求的URL地址时,方法如下:StringlookupPath=initLookupPath(request);两种方法相比,主要是initLookupPath方法中多了usesPathPatterns的选项,这是Spring5的新东西,所以今天松哥通过一篇简单的文章给大家分享一下usesPathPatterns到底是什么以及怎么玩它!这是一个不小的变化!特别是如果你的项目中使用了WebFlux,那么这个东西就尤为重要了!1.AntPathMatcher当我们使用@RequestMapping注解来标记请求接口时(或者使用它类似的方法如@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping),我们可以使用一些通配符来匹配URL地址,例如一个简单的例子,假设我有以下五个接口:@GetMapping("/hello/**/hello")publicStringhello(){return"/hello/**/hello";}@GetMapping("/h?llo")publicStringhello2(){return"/h?llo";}@GetMapping("/**/*.html")publicStringhello3(){return"/**/*.html";}@GetMapping("/hello/{p1}/{p2}")publicStringhello4(@PathVariableStringp1,@PathVariableStringp2){System.out.println("p1="+p1);System.out.println("p2="+p2);返回“/你好/{p1}/{p2}";}@GetMapping("/{名称:[a-z-]+}-{版本:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")publicvoidhandle(@PathVariableStringname,@PathVariableStringversion,@PathVariableStringext){System.out.println("name="+name);System.out.println("version="+version);System.out.println("ext="+ext);}在解释接口含义之前,先说说这几个通配符的含义:通配符含义**匹配0个或多个目录*匹配0个或多个字符?匹配任意单个字符理解了通配符的含义后,再说说每个接口可以接收到哪些请求:第一个接口可以接收请求比如/hello/123/123请求比如/hello,/hello/a/hello和/hello/hello,因为中间的**代表0个或多个目录。第二个接口可以接收/hallo,/hello,/hMllo等请求,注意不能接收/haallo或/hllo,因为?代表一个字符。第三个接口可以接收任何request后缀为.html,例如/aaa/bb/cc.html、/aa.html或/aa/aa.html。第四个界面想必大家都很熟悉吧。RESTful风格的界面设计,估计大家都用过。它接收到的请求格式类似于/hello/aa/bb,其中参数p1对应aa,参数p2对应bb。第五个接口使用正则表达式,name、version、ext三种参数格式用正则表达式表示,可以接收/spring-web-3.0.5.jar等格式的请求,最终参数名称为spring-web,版本是3.0.5,ext是.jar。这是之前在SpringMVC中就有的一个功能,不管你有没有用过,反正它是存在的。那么是谁支持这个功能呢?那就是AntPathMatcher。AntPathMatcher是Ant风格的路径匹配器。Ant风格的路径规则其实就是我们前面介绍的三种路径匹配器,非常easy。此路径匹配规则来自ApacheAnt项目(https://ant.apache.org)。ApacheAnt现在我们用的很少了。它的替代者是著名的Maven。如果你有幸维护一些2010年之前的老项目,就有可能接触到Ant。AntPathMatcher其实在SpringMVC中的应用非常广泛,不仅是在@RequestMapping中定义接口,其他涉及到地址匹配的地方也可以使用。比如我们在SpringMVC的配置文件中配置静态资源过滤Ant风格的路径匹配:另外拦截器中会使用Ant进行拦截路径注册,跨域处理等过程中的路径匹配。样式化的路径匹配器。总体来说,AntPathMatcher是Spring中比较原始的路径匹配方案。虽然比较简单,但是在处理URL编码时效率很低,不方便。因此,Spring5中就有了PathPattern。2.PathPatternPathPattern是专门为web应用设计的。它的大部分功能与之前的AntPathMatcher类似。当然,也有一些细微的差别,这个以后松哥再说。如果是Servlet应用,目前官方推荐的URL匹配方案是PathPattern(当然你也可以选择更早的AntPathMatcher)。虽然官方推荐的是PathPattern,但是还是默认使用了AntPathMatcher;如果您使用WebFlux,PathPattern是唯一的解决方案。注意PathPattern是一个很新鲜的东西。Spring的最新版本是5.3.4。在Spring5.3之前,我们在Servlet应用中只能选择AntPathMatcher。Spring5.3之后,可以使用PathPattern了。.PathPattern会将URL规则预解析到PathContainer中,可以更快的处理URL地址匹配。PathPattern和AntPathMatcher的区别主要体现在两个方面:首先,PathPattern只支持在末尾使用**,如果在路径中间使用**会报错。上面的第一个和第三个接口在PathPattern模式下会报错,如下:因为在中间或者开头使用**容易造成混淆,所以PathPattern只支持在最后使用**。其次,PathPattern支持使用{*path}等方法进行路径匹配,也可以匹配多层路径,并将匹配到的值赋值给path变量,比如如下接口:@GetMapping("/javaboy/{*path}")publicvoidhello6(@PathVariableStringpath){System.out.println("path="+path);}如果请求路径为http://localhost:8080/javaboy/aa,则值为参数路径为/aa;如果请求路径是http://localhost:8080/javaboy/aa/bb/cc/dd,那么参数path的值为/aa/bb/cc/dd;这种写法也比较新颖,因为之前的AntPathMatcher是没有这个的。3、如何使用SpringMVC中默认还是使用AntPathMatcher,那么如何启用PathPattern呢?很简单,只需要在SpringBoot项目中添加如下配置即可:}}添加这个配置后,在我们文章开头贴出的代码中,会进入if分支,然后使用PathPattern解析请求URL。4.总结今天和小伙伴说了这么多,大家可以体验一下这玩意,但是要注意选择Spring的版本,一定要选择5.3以上的版本!

猜你喜欢