SpringBoot中HandlerInterceptorAdapter使用

簡介:
在SpringBoot中我們可以使用HandlerInterceptorAdapter這個適配器來實現自己的攔截器。這樣就可以攔截所有的請求並做相應的處理。

應用場景

日誌記錄,可以記錄請求信息的日誌,以便進行信息監控、信息統計等。 權限檢查:如登陸檢測,進入處理器檢測是否登陸,如果沒有直接返回到登陸頁面。
性能監控:典型的是慢日誌。

在HandlerInterceptorAdapter中主要提供了以下的方法:
preHandle:在方法被調用前執行。在該方法中可以做類似校驗的功能。如果返回true,則繼續調用下一個攔截器。如果返回false,則中斷執行,也就是說我們想調用的方法 不會被執行,但是你可以修改response爲你想要的響應。
postHandle:在方法執行後調用。
afterCompletion:在整個請求處理完畢後進行回調,也就是說視圖渲染完畢或者調用方已經拿到響應。

實現
1.自定義一個類繼承HandlerInterceptorAdapter


@Service
public class AccessInterceptor extends HandlerInterceptorAdapter {
	//用map來代替redis測試
    private static Map<String,Integer> map=new ConcurrentHashMap<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //自定義攔截器

        if(handler instanceof HandlerMethod){


            String name=request.getParameter("name");
           

            HandlerMethod hm = (HandlerMethod)handler;
           //搭配自定義註解使用
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if(accessLimit == null) {
                return true;
            }
            int seconds = accessLimit.maxCount();
            if(map.getOrDefault(name,0)>seconds){//超過最大次數 不給通過
                return false;
            }else{
                map.put(name,map.getOrDefault(name,0)+1);
            }

        }

        return true;
    }
}

2.註冊到WebMvcConfigurerAdapter中

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    AccessInterceptor accessInterceptor;

    /**
     * 註冊accessInterceptor才能正常使用
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(accessInterceptor);
    }
}

兩步即可完成攔截實現。

另外可以在自定義攔截裏面搭配註解使用。比如實現短時間限定用戶訪問次數。可考慮搭配redis使用

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {

    int maxCount();//一定時間內的訪問次數
    boolean needLogin() default true;
}

controller層使用,在需要攔截的方法上面加註解並設置最大值

  	@AccessLimit(maxCount = 5)//最大設置爲5
    @GetMapping("/access/{name}/{age}")
    @ResponseBody
    public String TestAccessLimit(HttpServletRequest request,@RequestParam("name") String name){
       //doSomething
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章