當然,一旦使用了通配符,就可能導緻比對的範圍過大的問題!畢竟有相同字首,但是字尾不同的若幹個請求路徑中,可能有些需要經過攔截器,而有些并不需要經過攔截器!例如:使用者注冊、使用者登入都不必經過“登入攔截器”,但是修改資料、修改密碼、修改頭像、驗證手機、驗證郵箱等諸多操作都是需要經過“登入攔截器”,就會存在“如果不使用通配符,就必須一個個的配置攔截路徑,工作量較大,如果使用通配符,可能将使用者注冊、使用者登入也比對進去,導緻比對過大”的問題!是以,SpringMVC還提供了配置“排除路徑”的做法,也就是“在已經配置的路徑範圍中排除某些路徑”,類似于“白名單”,其方法是:
public InterceptorRegistration excludePathPatterns(String... patterns) {
return excludePathPatterns(Arrays.asList(patterns));
}
public InterceptorRegistration excludePathPatterns(List<String> patterns) {
this.excludePatterns.addAll(patterns);
return this;
}
例如,可以配置為:
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/user/**")
.excludePathPatterns("/user/reg.do", "/user/login.do");
以上代碼就表示“以/user/開頭的路徑都是需要被攔截的,但是,/user/reg.do和/user/login.do這2個路徑是例外的,不需要被攔截器處理”。
5. 過濾器與攔截器的差別
相似之處:
都可以使得若幹個請求路徑都執行過濾器元件/攔截器元件中的代碼片斷,都可以在執行之後選擇“阻止”或“放行”,都有“鍊”的概念。
差別:
過濾器Filter是Java EE中的元件,隻要是Java Web項目都可以使用過濾器,包括在SpringMVC項目中也可以使用過濾器;攔截器Interceptor是SpringMVC架構中的元件,隻有使用了SpringMVC架構的項目,才可以使用攔截器,并且,隻有被SpringMVC架構處理的請求才可能被攔截器所處理,例如,将DispatcherServlet映射的路徑(在SpringMvcInitializer中getServletMappings()方法的傳回值)配置為*.do時,隻有以.do為字尾的請求才可能被攔截器處理,而例如.jpg類似的請求将不會被攔截器處理,當然,如果有必要的話,也可以将DispatcherServlet映射的路徑配置為/*,則任何請求都可能被攔截器處理。
過濾器Filter可以配置若幹個映射路徑,可以使用通配符,但是,卻不能從中剔除部分請求路徑,也就是“不能配置白名單”,在配置時可能比較麻煩;攔截器Interceptor在配置映射的請求路徑時,既可以配置攔截路徑(黑名單),又可以配置排除路徑(白名單),配置更加簡單、靈活。
過濾器Filter是執行在所有Servlet元件之前的;而攔截器Interceptor的第1次執行是在DispatcherServlet之後,且在Controller之前的。
小結:
在SpringMVC項目中,應該優先使用攔截器Interceptor元件,除非某些代碼片斷必須在Servlet之前執行!
1. 關于@RequestMapping注解
在控制器類中,在處理請求的方法之前使用@RequestMapping,可以綁定請求路徑與處理請求的方法,以至于當用戶端請求該路徑時,對應的方法就會被調用!
其實,還可以在控制器類的聲明之前也添加該注解!例如:
@Controller
@RequestMapping("user")
public class UserController {
}
則該控制器中所有請求路徑的資源名(各處理請求的方法之前配置的值)左側都需要添加類上配置的值!
假設在以上UserController中,沒有為類配置@RequestMapping之前,存在以下請求路徑:
http://localhost:8080/springmvc/reg.do
http://localhost:8080/springmvc/login.do
注:以上路徑中的springmvc是Context Path值。
為類配置了@RequestMapping("user")之後,請求路徑就需要改為:
http://localhost:8080/springmvc/user/reg.do
http://localhost:8080/springmvc/user/login.do
在實際開發項目時,推薦為每一個控制器類之前配置該注解!
在控制器類之前也配置了@RequestMapping後,其配置值會與方法之前的@RequestMapping的配置值組合起來,形成完整的路徑,無論是将@RequestMapping配置在哪個位置,在配置注解屬性時,架構會自動添加必要的/,并且兩端多餘的/都是會忽略的!例如,以下各種配置方式是完全等效的:

是以,在實際應用時,一般推薦使用以上表格中的第1種做法,或第4種做法,也就是“要麼在注解參數的左側都不添加/符号,要麼都添加/符号”。
關于@RequestMapping注解,其源代碼中存在:
@AliasFor("path")
String[] value() default {};
基于value是注解中的預設屬性,是以,一直以來,使用@RequestMapping注解時配置的值,其實都是這個value屬性的值,也就是說,以下2種配置方式是完全等效的:
@RequestMapping("reg.do")
@RequestMapping(value = "reg.do")
由于在注解中聲明的value的類型是String[]數組,是以,以上2種配置與以下2種配置都是完全等效的:
@RequestMapping({ "reg.do" })
@RequestMapping(value = { "reg.do" })
當注解參數的類型是某種數組類型,且需要配置的值隻有1個值時,将該屬性直接配置為數組元素的值,或配置為數組類型的值,都是允許的,且是等效的!
同時,基本該屬性是數組類型的,是以,其實是可以配置多個路徑的,例如:
@RequestMapping({ "reg.do", "register.do" })
如果注解參數中為value屬性配置了2個值,就表示“通過這2個配置的請求路徑中的任何一個都可以使得映射的方法被調用”!