一 案例
<mvc:interceptors>
<mvc:interceptor>
<!-- 对所有的.do结尾的进行拦截,/**表示/下面任何字段,起初我用/*/*.do后来发现/*不能代表所有的字段,要使用/** -->
<mvc:mapping path="/**/*.do" />
<!-- 登录 -->
<mvc:exclude-mapping path="/**/login.do" />
<mvc:exclude-mapping path="/**/findDepartmentsBeforLogin.do" />
<!--退出 -->
<mvc:exclude-mapping path="/**/loginOut.do" />
<!-- 跳转登录页面 -->
<mvc:exclude-mapping path="/**/toLogin.do" />
<bean class="com.xxx.interceptor.login.LoginInterceptor">
<!--adminId 配置是为了开发人员使用的权限 -->
<!-- <property name="adminId" value="1"/> -->
</bean>
</mvc:interceptor>
</mvc:interceptors>
二 路径通配符匹配方法
Wildcard | Description | |
? | 匹配任何单字符 | |
* | 匹配0或者任意数量的字符 | |
** | 匹配0或者更多的目录 |
1案例
Path | Description | |
/app/*.x | 匹配(Matches)所有在app路径下的.x文件 | |
/app/p?ttern | 匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern | |
/**/example | 匹配(Matches) /app/example, /app/foo/example, 和 /example | |
/app/**/dir/file. | 匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java | |
/**/*.jsp | 匹配(Matches)任何的.jsp 文件 |
三 HandlerMapping
- Spring提供了URL的映射处理, 并且处理路径模式的顺序和方法并没有限定到任何的接口上。
- Spring MVC的默认实现org.springframework.web.servlet.handler. AbstractUrlHandlerMapping, 会以最长符合路径模式来匹配一个路径。
- 例如:
- 给定一个请求是 /app/dir/file.jsp 并且现在存在两个路径匹配模式/**/*.jsp 和/app/dir/*.jsp, 那么,URL会匹配那个模式呢?最后的那个模式/app/dir/*.jsp,会因为最长的原则被匹配,它比/**/*.jsp拥有更多的字符,注意的是,这个原则并没有在任何高级别的接口中指定,但却是一种实现细节。
- 例如:
3.1 下面看一下默认的两个HandlerMapping
1. BeanNameUrlHandlerMapping
默认的映射策略实现是org.springframework.web. servlet.handler.BeanNameUrlHandlerMapping类.
这个类要求任何有可能处理请求的Bean都要起一个以反斜杠(/)字符开头的名称或者别名,这个名称或者别名可以是符合URL Path匹配原则中的任何名字。
案例
xml 代码<bean name="/home" class="com.apress.expertspringmvc.flight.web.HomeController">
<property name="flightService" ref="flightService" />
</bean>
1.1.注意:
- 你不能使用id这个属性来指定任何的URL路径,因为在XML规格定中禁止(/)字符来指定XML的id,不过你可以在一个Bean定义中同时拥有id和name属性
- 它非常便于使用的同时,也拥有一些缺点。它不能影射一个Prototype的Bean.换句话说,当使用 BeanNameUrlHandlerMapping时, 所有的请求处理类只能是单例的(singletons) . 一般来说,Controllers都是按照单例建立的,所以这个并不是一个很严重的问题
- Prototype bean 是一种非单例(non-singleton)的bean. 任何一次调用ApplicationContext的getBean()方法时都会返回一个新的Bean实例.
1.2 BeanNameUrlHandlerMapping的另外一个问题存在于应用拦截(interceptor).
因为请求的映射(handler mapping )和Bean(beans imapping)的映射给绑定在一起了,没有分开,这样就不可能在Controller和拦截之间创建复杂的关系。如果有复杂的请求映射需求,你可以用 SimpleUrlHandlerMapping 来代替BeanNameUrlHandlerMapping.
2. SimpleUrlHandlerMapping
- 它可以映射 prototype类型的请求处理器,并且它允许你为处理器(handlers)和拦截器(interceptors)之间创建复杂灵活的映射路径的映射算法
- 这个模式依然是映射URL到请求处理器的(request handler) ,你简单的在ApplicationContext中声明一下,就可以使用SimpleUrlHandlerMapping了. DispatcherServlet会根据类型找到的,并