java程序路径通配符表达式合辑

来源:互联网 发布:poe交换机端口不供电 编辑:程序博客网 时间:2024/06/06 05:48

目前这里整合了java、ant、springmvc的路径表达式规范,并会持续更新如果实际有变。

Patterns:表达式,规则。PatternSet:表达式序列,表达式清单。matches:相对,匹配。directory:目录。


下面是翻译ant文档的解释:

正如前面所述,patterns用于对文件的包含和不包含。这些patterns看上去和DOS和UNIX中使用的patterns非常相似:

'*' matches 0个或多个字符,'?' matches 一个字符。

通常,patterns侧重于相对路径,这个相对路径依赖于工作的基础目录(或者文件清单fileset)。只有这个基础目录下的被发现的文件才会识别。所以当有一个pattern像 ../foo.java这样的话,尽管被认为是合理的,但是不会matche任何东西因为基础目录的上级是不会被扫描的。


例子:

*.java matchs .java , x.java 或者Foobar.java ,但是Foobar.xml是不行的。因为后缀不是java。

?.java matchs x.java , A.java ,但是 .java 或者 xyz.java是不行的,因为后面两者是0个或者多于一个字符。

*号和?号是可以组合使用的。


匹配是按每一个目录进行的。这意味着首先第一个目录匹配通过,下一级的目录才能进行匹配,直到结束。例如:有一个pattern/?abc/*/*.java和一个路径/xabc/foobar/test.java,第一个?abc匹配到了xabc,那么*就会匹配foobar,最后*.java匹配test.java。当他们全部都匹配上了,这条路径才算匹配通过。


为了更灵活的使用,我们添加了扩展特性,令其可以匹配多个级别的目录。这样可以用于匹配一个完整的目录树,或者树的所有文件。要使用这一点,必须把**跟在目录名后面才可以。当**在patterns中的跟在目录名后面,那么matches的是0个或者多个目录。例如:/test/** matches /test/下的所有文件和目录,像/test/x.java这样的或者/test/foo/bar/xyz.html这样的,但是/xyz.xml这样的是不行的。


这里有一个速记法则:如果patterns是以/或者\结尾,那么**是追加。


下面是一些路径匹配的示例:

**/CVS/*Matches all files inCVS directories that can be located anywhere in the directory tree.
Matches:

      CVS/Repository      org/apache/CVS/Entries      org/apache/jakarta/tools/ant/CVS/Entries      
But not:
      org/apache/CVS/foo/bar/Entries (foo/bar/      part does not match)      
org/apache/jakarta/**Matches all files in theorg/apache/jakarta directory tree.
Matches:
      org/apache/jakarta/tools/ant/docs/index.html      org/apache/jakarta/test.xml      
But not:
      org/apache/xyz.java      
(jakarta/ part is missing).org/apache/**/CVS/*Matches all files inCVS directories that are located anywhere in the directory tree underorg/apache.
Matches:
      org/apache/CVS/Entries      org/apache/jakarta/tools/ant/CVS/Entries      
But not:
      org/apache/CVS/foo/bar/Entries      
(foo/bar/ part does not match)**/test/**
Matches all files that have atest element in their path, includingtest as a filename.


对于springmvc:springmvc中是支持ant方式的定义,与其说支持,不如说只直接照搬过来并进行扩展。


在springframework中,对于mvc,spring的分发器dispatcher支持上述的 *  ,但不支持**扩展。在处理静态资源的时候会用到resource标签,其中的mapping和location则支持 * , **。


spring的resource标签和interceptor标签,以及requestmapping的路径支持ant方式。并且具有如下原则:

这里用翻译spring官方文档中的22.3.2章节中url pattern中的一段描述:

在添加uri模板中,@requestMapping注解和所有@requestMapping的变种都支持ant风格的路径表达式(例如,/myPath/*.do)。同样也支持一个uri模板变量和ant风格的组合(e.g./owners/*/pets/{petId})。


当一个url匹配多重的patterns,可以根据一种顺序来确定匹配的最高优先级。


1、一个有更少uri变量以及通配符的pattern具有更高的优先级。例如/hotels/{hotel}/*有一个uri变量和1个通配符,相对/hotels/{hotel}/**具有2个通配符,前者的优先级更高。可以理解为*越少优先级越高。


2、如果两者里面的数量都相同,长度长的优先级更高。例如/foo/bar*比/foo/*优先级更高。


3、当两者数量和长度都相同的情况下,通配符越少优先级越高。例如/hotels/{hotel}比/hotels/*优先级高,可以理解为没*比有*优先级高。


这里还有一些附加的规则:

  • 默认的映射表达式default mapping pattern/**比其他pattern优先级都低。例如/api/{a}/{b}/{c}更高。
  • 像/public/**这样前缀的pattern优先级比其他任何不包含**的pattern优先级都要低。例如/public/path3/{a}/{b}/{c}优先级更高。

具体详细解释在AntPathMatcher中的AntPatternComparator中。也就是上面的ant部分说明,我已经翻译过来了。