一、/*
是一种通配的写法,可匹配所有的url。
注意:
/*
可以匹配所有的url,但是并不一定会最终拦截这些url。
当一个url匹配多个url-pattern时,会按照一定的优先顺序进行选择。而/*
的优先级并不是最高的。
具体的说,它们的优先顺序是:
- 精确匹配
- 通配符路径匹配(且匹配路径越长,越优先)
- 文件扩展名匹配
/
匹配
二、/
捡漏王
从上面的匹配优先顺序,我们可以看出一些端倪。如果一个servlet的url-pattern是/
,那么如果一个url没有击中任何其它的servlet时,它就会被这个"/
servlet"拦截。所以它是名副其实的"捡漏王"。
常见的一种错误理解是,/
和/*
一样是某种通配符路径匹配,这是不对的。
三、tomcat内置servlet
我们编写servlet程序时,会为每一个自定义的servlet配置一个url-pattern,使得它可以处理对应的请求。但是我们是否想过,当我们请求jsp页面或者html、css、js时,这些请求是如何处理的呢?
这些请求的处理就是由tomcat的内置servlet来完成的。
这里介绍两个重要的内置servlet(好吧,其实是其它的我也看不懂)
1.default servlet
它的url-pattern是:
<url-pattern>/</url-pattern>
它就是tomcat为我们默认提供的"捡漏王"。主要用来处理访问静态资源的请求。
2.JSP servlet
它的url-pattern是:
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
它主要用来处理访问jsp页面的请求。
四、问题思考
结合/
和/*
的含义,url-pattern的匹配优先顺序,以及tomcat的两个内置servlet。你是否可以回答以下两个问题?
1.SpringMVC前端控制器的url-pattern为/
,它可以拦截几乎所有请求,但为什么不包括访问jsp页面的请求?
2.SpringMVC前端控制器的url-pattern为/*
,它为什么可以拦截几乎所有请求,包括访问jsp页面的请求?
答案
1.当SpringMVC前端控制器的url-pattern是/
时,它就代替default servlet成为了新的"捡漏王",所有没有命中其它任何servlet的请求,都会被它拦截。但是由于tomcat有内置的JSP servlet,所以访问jsp页面的请求会被JSP servlet拦截。根据优先顺序也可以知道,文件扩展名匹配的优先级大于/
的优先级。
2.当SpringMVC的前端控制器url-pattern是/*
时。根据优先级顺序,通配符路径匹配的优先级大于文件扩展名匹配优先级,所以访问jsp页面的请求会被前端控制器拦截,而不会命中JSP servlet。
参考文章
https://www.jb51.net/article/144487.htm
https://help.perforce.com/hydraexpress/3.5.0/html/rwsfservletug/4-3.html
https://stackoverflow.com/questions/4140448/difference-between-and-in-servlet-mapping-url-pattern