在开始介绍Spring DispatcherServlet的通配符之前,先简单说说servlet的mapping中使用通配符
在web.xml文件中配置servlet-mapping 的url-pattern可以使用通配符(*), 但这个通配符的使用有非常严格的限制,只能用于以下两种情况:
1. *.[extension], 匹配扩展名请求, 如:/product/*.do;
2. 以“/”开头并以“/*”结束,如:/product/*;
一个Servlet在web.xml中可以配置多个servlet-mapping,这也就意味着多个servlet-mapping之间可能有冲突 ,所以各种mapping规则之间的优先级也是需要在配置的时候考虑的,优先匹配规则如下:
1. 优先匹配精确的urlPattern;
2. 优先匹配更长的urlPattern, 如:/product/list/*的优先级比/product/*高;
3. 优先匹配含有扩展的urlPattern;
言归正传,回到DispatcherServlet.
Spring 的DispatcherServlet本身继承自HttpServlet, 所以在web.xml中配置DispatcherServlet和配置其他Servlet没什么区别,那么配置DispatcherServlet的urlPattern时使用*还要注意什么吗?
我们假设我们要开发一个restful风格的api,url是:http://localhost/product/list,
为此我们准备了一个ProductController类,这个类有一个list方法:
@RequestMapping("/product")
public class ProductController {
@RequestMapping("list")
public String list(Map<String, Object> model){...}
}
那为了让DispatcherServlet只处理/product路径下的请求,我们要配置DispatcherServlet的urlPattern为:
/product/*
看起来好像就没有问题了,但是我们用浏览器访问以下http://localhost/product/list得到的肯定是:404
我们检查一下urlPattern和@RequestMapping似乎找不出什么问题出来,看起来问题出现的有点莫名其妙。
好,我们按照以下三个方法分别debug一下:
1. urlPattern换成/product/list;
or
2.访问http://localhost/product/product/list;
or
3.移除@RequestMapping("/product")
会发现都能访问了。
分析一下我们可以确定的是在使用*配置urlPattern的情况下, DispatcherServlet在接收到http请求后,要转给哪个controller来处理并不是完全根据urlPattern来的(具体DispatcherServlet怎么处理urlPattern请关注后续博文DispatcherSerlvet源码解析之url),而是根据*匹配的部分。
在这个例子中:
/product/*中*匹配上的是“list”, DispatcherServlet会把请求转发给有@RequestMapping(“list”)注解的controller方法