在Spring MVC中經常要用到攔截器,在配置需要要攔截的路徑時經常用到<mvc:mapping/>子標籤,其有一個path屬性,它就是用來指定需要攔截的路徑的。例如:
<mvc:interceptor><mvc:mapping path="/**" /><bean /></mvc:interceptor></mvc:interceptor>
根據以上配置,此攔截器會攔截所有的請求。
Spring MVC中的路徑匹配要比標準的web.xml要靈活的多。默認的策略實現了org.springframework.util.AntPathMatcher,就像名字提示的那樣,路徑模式是使用了Apache Ant的樣式路徑,Apache Ant樣式的路徑有三種通配符匹配方法(在下面的表格中列出),這些可以組合出很多種靈活的路徑模式
Table Ant Wildcard Characters
Wildcard | Description |
| ? | 匹配任何單字符 |
| * | 匹配0或者任意數量的字符 |
| ** | 匹配0或者更多的目錄 |
Table Example Ant-Style Path Patterns
| 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
一個WEB應用程序基本上都要依賴於URL與請求處理器之間的映射,Spring MVC也是一樣,但Spring MVC就像Spring所作的一切一樣(譯者:靈活,可以配置各種東西,但是也造成了很多複雜性),肯定不會只有一種方法來映射URL和Controller之間的關係,並且在實際上,允許你自己創建映射規則和實現,而不僅僅依賴URL映射。
Spring提供了URL的映射處理, 並且處理路徑模式的順序和方法並沒有限定到任何的接口上。 Spring MVC的默認實現org.springframework.web.servlet.handler. AbstractUrlHandlerMapping, 會以最長符合路徑模式來匹配一個路徑。
例如:給定一個請求是/app/dir/file.jsp 並且現在存在兩個路徑匹配模式/**/*.jsp 和/app/dir/*.jsp, 那麼,URL會匹配那個模式呢?最後的那個模式/app/dir/*.jsp,會因為最長(has more characters)的原則被匹配,它比/**/*.jsp擁有更多的字符.注意的是,這個原則並沒有在任何高級別的接口中指定,但卻是一種實現細節。
BeanNameUrlHandlerMapping
默認的映射策略實現是org.springframework.web. servlet.handler.BeanNameUrlHandlerMapping類. 這個類要求任何有可能處理請求的Bean都要起一個以反斜杠(/)字符開頭的名稱或者別名,這個名稱或者別名可以是符合URL Path匹配原則中的任何名字。
Listing A Controller Mapped by a Bean Name
xml 代碼
<bean name="/home"> <property name="flightService" ref="flightService" /> </bean>
■注意:你不能使用id這個屬性來指定任何的URL路徑,因為在XML規格定中禁止(/)字符來指定XML的id,不過你可以在一個Bean定義中同時擁有id和name屬性
它非常便於使用的同時,也擁有一些缺點。它不能影射一個Prototype的Bean.換句話說,當使用BeanNameUrlHandlerMapping時, 所有的請求處理類只能是單例的(singletons) . 一般來說,Controllers 都是按照單例建立的,所以這個並不是一個很嚴重的問題.還有,我會在後面的章節中介紹Controller,只會有很少類型的Controller需要是prototypes.
■註釋: Prototype bean 是一種非單例(non-singleton)的bean. 任何一次調用ApplicationContext的getBean()方法時都會返回一個新的Bean實例.
BeanNameUrlHandlerMapping的另外一個問題存在於在你的應用程序中應用攔截(interceptor). 因為請求的映射(handler mapping )和Bean(beans imapping)的映射給綁定在一起了,沒有分開,這樣就不可能在Controller和攔截之間創建複雜的關係。如果有復雜的請求映射需求,你可以用SimpleUrlHandlerMapping 來代替BeanNameUrlHandlerMapping. SimpleUrlHandlerMapping作為BeanNameUrlHandlerMapping的另外一種選擇, SimpleUrlHandlerMapping直指BeanNameUrlHandlerMapping的兩大軟肋.它可以映射prototype類型的請求處理器,並且它允許你為處理器(handlers)和攔截器(interceptors)之間創建複雜靈活的映射路徑的映射算法與BeanNameUrlHandlerMapping是使用相同的基礎組件,所以這個模式依然是映射URL到請求處理器的(request handler) ,你簡單的在ApplicationContext中聲明一下,就可以使用SimpleUrlHandlerMapping了. DispatcherServlet會根據類型找到的,並且不會創建默認的映射器了(BeanNameUrlHandlerMapping).意思就是, 如果你想兩個都用,那麼就要全部聲明一下在ApplicationContext裡.
■提示DispatcherServlet會鍊式處理請求的(譯者:依次處理請求,可以參照過濾器和GOF中的責任鏈模式),這樣允許按照你的要求處理映射,映射處理器(Handler mappings )實現了Orderedr接口.
以上就是本文關於spring mvc路徑匹配原則詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!