本文描述的是在springmvc中威酒,通過注解清除(跳過)攔截器损肛,支持在Controller類級別或者方法級別來清除稀并,可同時清除多個攔截器昂拂。
在開發(fā)web后臺時鞭缭,我們的接口一般都需要加權限控制。比如一個簡單的場景:用戶需要登錄后才能訪問魏颓,沒登錄就直接跳轉登錄界面或者返回特定的錯誤碼岭辣。通常我們會配置一個攔截器,驗證一下用戶請求攜帶的token甸饱,如果驗證通過就返回true. 這時候有這么一個需求:幾乎所有的controller都需要攔截沦童,但某幾個Controller或者Controller里面的方法需要跳過攔截器,比如用戶登錄的接口和錯誤處理的接口叹话,雖然這時候我們可以在配置爛機器的時候配置忽略路徑偷遗,但這樣不夠靈活。前幾天用注解實現(xiàn)了這一功能驼壶,這里做一個簡單描述氏豌。
首先創(chuàng)建一個注解,內(nèi)容很簡單热凹,value為一個包含要清除的攔截器的數(shù)組泵喘。
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Clear {
Class<? extends HandlerInterceptor>[] value() default {};
}
接下來要在你的攔截器里面來獲取當前請求對應的方法或者該方法所處的類上面是否有清除當前攔截器的注解泪电。如果有就直接返回true。比如我有一個ApiInterceptor纪铺,主要代碼如下:
public class ApiInterceptor implements HandlerInterceptor {
//只列出主要代碼
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
HandlerMethod m= (HandlerMethod) o;
Method method=m.getMethod();
//判斷是否用注解清除
if(clearedByAnnotation(method)){
return true;
}
//其他操作相速,比如驗證token
httpServletResponse.sendRedirect("/api/error/401");
return false;
}
private boolean clearedByAnnotation(Method method){
Clear clear=method.getAnnotation(Clear.class);
if(clear!=null){
if(Arrays.asList(clear.value()).contains(ApiInterceptor.class)){
return true;
}
}
Class clazz=method.getDeclaringClass();
clear= (Clear) clazz.getDeclaredAnnotation(Clear.class);
if(clear!=null){
if(Arrays.asList(clear.value()).contains(ApiInterceptor.class)){
return true;
}
}
return false;
}
}
然后,在使用的時候鲜锚,我們只需要在Controller或者Controller里面的方法上面加上Clear注解即可:
@RestController
@RequestMapping("/api/user")
public class UserApi {
@PostMapping("/login/{code}")
@Clear(ApiInterceptor.class)
public Res doLogin(@PathVariable String code, HttpServletRequest req){
// TODO
return Res.ok;
}
}
清除多個攔截器:
@RestController
@RequestMapping("/api/error")
@Clear({ApiInterceptor.class,AdminInterceptor.class})
public class ErrorApi {
@RequestMapping("/{code}")
public Res error(@PathVariable int code){
return Res.fail.code(code);
}
}
然后突诬,就沒有然后了,這樣就ok了芜繁,雖然說代碼多一點旺隙,但比起配置忽略路徑要更靈活,最重要的是更能裝X浆洗。然后補充一點催束,如果攔截器比較多的話,每個都這么配會比較繁瑣伏社,可以寫一個BaseInterceptor, 然后其他攔截器繼承就可以抠刺。
你說我是有多無聊,無聊到開始上班寫博客玩了……