SpringMVC中使用注解清除攔截器

本文描述的是在springmvc中,通過注解清除(跳過)攔截器,支持在Controller類級別或者方法級別來清除,可同時清除多個攔截器。

在開發web后臺時,我們的接口一般都需要加權限控制。比如一個簡單的場景:用戶需要登錄后才能訪問,沒登錄就直接跳轉登錄界面或者返回特定的錯誤碼。通常我們會配置一個攔截器,驗證一下用戶請求攜帶的token,如果驗證通過就返回true. 這時候有這么一個需求:幾乎所有的controller都需要攔截,但某幾個Controller或者Controller里面的方法需要跳過攔截器,比如用戶登錄的接口和錯誤處理的接口,雖然這時候我們可以在配置爛機器的時候配置忽略路徑,但這樣不夠靈活。前幾天用注解實現了這一功能,這里做一個簡單描述。

首先創建一個注解,內容很簡單,value為一個包含要清除的攔截器的數組。

@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, 然后其他攔截器繼承就可以。

你說我是有多無聊,無聊到開始上班寫博客玩了……

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,973評論 19 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,970評論 6 342
  • 此刻躺在床上,洗澡完畢,回家的感覺實在是太好了。感恩我們順利的回到家。感恩 感謝一切的美好 感恩早上婆婆做了做了我...
    能量團隊閱讀 207評論 0 0
  • 嘉賓:檢察官、法官、學者、法科生、普通民眾 檢:大家好,我是內蒙古通遼市檢察院的一名普通檢察官。我這次春節前后到內...
    翱翔的飛燕閱讀 393評論 0 0
  • 8:00 我起床了,邊“喔喔喔喔”地喊道邊使勁蹬腿踢被子扭扭身子,將火車頭吵醒。火車頭打戰似的將我伺候好后,還沒...
    月下梨花閱讀 363評論 0 2