zoukankan      html  css  js  c++  java
  • Spring源码解析

    最近在看SpringMVC的源码,发现request分发时,路径匹配最后是委托给AntPathMatcher实现的.索性看看吧.

    文章摘要:

      1. ant匹配规则

      2. PathMatcher接口

      3. 通过测试用例看AntPathMatcher的使用

     

    ant匹配规则

    AntPathMatcher如名使用的ant 的匹配规则,我们先看看吧.

      字符wildcard    描述

       ?         匹配一个字符

       *         匹配0个及以上字符

       **         匹配0个及以上目录directories

    看几个官方的例子吧:

      com/t?st.jsp -             匹配: com/test.jsp  ,  com/tast.jsp  ,  com/txst.jsp
      com/*.jsp -             匹配: com文件夹下的全部.jsp文件
      com/**/test.jsp -          匹配: com文件夹和子文件夹下的全部.jsp文件,
      org/springframework/**/*.jsp -    匹配: org/springframework文件夹和子文件夹下的全部.jsp文件
      org/**/servlet/bla.jsp -       匹配: org/springframework/servlet/bla.jsp  ,  org/springframework/testing/servlet/bla.jsp  ,  org/servlet/bla.jsp

    PathMatcher接口

    主要是判断是否匹配pattern,并解析出path中的参数

     1 package org.springframework.util;
     2 
     3 public interface PathMatcher {
     4 
     5     /**
     6      * 判断传入的path是否可以作为pattern使用
     7      */
     8     boolean isPattern(String path);
     9 
    10     /**
    11      * 使用pattern匹配path
    12      */
    13     boolean match(String pattern, String path);
    14 
    15     /**
    16      * 如名,是否开始部分匹配
    17      */
    18     boolean matchStart(String pattern, String path);
    19 
    20     /**
    21      * 提取path中匹配到的部分,如pattern(myroot/*.html),path(myroot/myfile.html),返回myfile.html
    22      */
    23     String extractPathWithinPattern(String pattern, String path);
    24 
    25     /**
    26      * 提取path中匹配到的部分,只是这边还需跟占位符配对为map,
    27      * 如pattern(/hotels/{hotel}),path(/hotels/1),解析出"hotel"->"1"
    28      */
    29     Map<String, String> extractUriTemplateVariables(String pattern, String path);
    30 
    31     /**
    32      * 提供比较器
    33      */
    34     Comparator<String> getPatternComparator(String path);
    35 
    36     /**
    37      * 合并pattern,pattern1然后pattern2
    38      */
    39     String combine(String pattern1, String pattern2);
    40 
    41 }

    通过测试用例看AntPathMatcher的使用

    一看测试用例,瞬间服了,人家开发真是规范.

    人家整这么规范,还是有空直接看源码好了.这边挑几个简单的例子看看就好

    1. match 跟 matchStart 的差异,这个我们在测试用例看下面的情况会比较明确

      这边的代码,我截取了一小部分

     1 package org.springframework.util;
     2 public class AntPathMatcherTests {
     3     @Test
     4     public void match() {
     5         // ...
     6         assertFalse(pathMatcher.match("/x/x/**/bla", "/x/x/x/"));
     7         // ...
     8     }
     9     @Test
    10     public void withMatchStart() {
    11         // ...
    12         assertTrue(pathMatcher.matchStart("/x/x/**/bla", "/x/x/x/"));
    13         // ...
    14     }
    15 }

    2. extractPathWithinPattern,代码很清楚,不废话

     1 package org.springframework.util;
     2 public class AntPathMatcherTests {
     3     @Test
     4     public void extractPathWithinPattern() throws Exception {
     5         // ...
     6         assertEquals("", pathMatcher.extractPathWithinPattern("/docs/commit.html", "/docs/commit.html"));
     7         assertEquals("cvs/commit", pathMatcher.extractPathWithinPattern("/docs/*", "/docs/cvs/commit"));
     8         assertEquals("docs/cvs/commit", pathMatcher.extractPathWithinPattern("/d?cs/*", "/docs/cvs/commit"));
     9         // ...
    10     }
    11 }

    3. extractUriTemplateVariables

     1 package org.springframework.util;
     2 public class AntPathMatcherTests {
     3     @Test
     4     public void extractUriTemplateVariables() throws Exception {
     5         Map<String, String> result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
     6         assertEquals(Collections.singletonMap("hotel", "1"), result);
     7         // ...
     8         result = pathMatcher.extractUriTemplateVariables("/{page}.*", "/42.html");
     9         assertEquals(Collections.singletonMap("page", "42"), result);
    10         // ...
    11     }
    12     /**
    13      * SPR-7787
    14      */
    15     @Test
    16     public void extractUriTemplateVarsRegexQualifiers() {
    17         Map<String, String> result = pathMatcher.extractUriTemplateVariables(
    18                 "{symbolicName:[\p{L}\.]+}-sources-{version:[\p{N}\.]+}.jar",
    19                 "com.example-sources-1.0.0.jar");
    20         assertEquals("com.example", result.get("symbolicName"));
    21         assertEquals("1.0.0", result.get("version"));
    22         // ...
    23     }
    24 }

    4. combine

     1 package org.springframework.util;
     2 public class AntPathMatcherTests {
     3     @Test
     4     public void combine() {
     5         // ...
     6         assertEquals("/hotels", pathMatcher.combine("/hotels", null));
     7         assertEquals("/hotels/booking", pathMatcher.combine("/hotels/*", "/booking"));
     8         assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "booking"));
     9         assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "/booking"));
    10         assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "/booking"));
    11         assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels/*", "{hotel}"));
    12         assertEquals("/hotels/**/{hotel}", pathMatcher.combine("/hotels/**", "{hotel}"));
    13         assertEquals("/hotels/*/booking/{booking}", pathMatcher.combine("/hotels/*/booking", "{booking}"));
    14     }
    15 }
  • 相关阅读:
    Java中Collection和Collections的区别(转载)
    equals和==的区别
    【转载】String、StringBuffer与StringBuilder之间区别
    Mybatis实现
    springMVC---文件上传
    java---Map接口实现类
    java---迭代器(Iterator)
    java---泛型
    java---StringBuilder类的用法(转载)
    c#开源项目收集
  • 原文地址:https://www.cnblogs.com/leftthen/p/5212221.html
Copyright © 2011-2022 走看看