1. 程式人生 > >SpringBoot 攔截器(Interceptor)的使用

SpringBoot 攔截器(Interceptor)的使用

img 直接 tin json.js author override and esp response

攔截器intercprot 和 過濾器 Filter 其實作用類似

在最開始接觸java 使用struts2的時候,裏面都是filter

後來springmvc時就用interceptor

沒太在意過區別,反正就是起檢查作用的,

仔細閱讀 過濾器(filter)和攔截器(interceptor)的區別 後明白了不少

最重要的要記住他們的執行順序: 先filter 後 interceptor

過濾前-攔截前-action執行-攔截後-過濾後

在了解上面的信息後,本文講interceptor的使用

自己定義的interceptor都需要繼承HandlerInterceptor 並實現對應方法preHandle postHandle來實現攔截功能

同時需要根據攔截規則進行註冊

實例如下:

技術分享圖片
package com.xiao.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.alibaba.fastjson.JSON;
import com.xiao.common.result.Error;
import com.xiao.common.result.Result;

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Bean
    public InterfaceAuthCheckInterceptor getInterfaceAuthCheckInterceptor() {
        return new InterfaceAuthCheckInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多個攔截器組成一個攔截器鏈
        // addPathPatterns 用於添加攔截規則
        // excludePathPatterns 用戶排除攔截
        registry.addInterceptor(getInterfaceAuthCheckInterceptor()).addPathPatterns("/api/**");
        // registry.addInterceptor(new InterfaceAuthCheckInterceptor()).addPathPatterns("/api/**");
        // 如果interceptor中不註入redis或其他項目可以直接new,否則請使用上面這種方式
        super.addInterceptors(registry);
    }

    
    /**
     * 微服務間接口訪問密鑰驗證
     * @author xiaochangwei
     *
     */
    class InterfaceAuthCheckInterceptor implements HandlerInterceptor {

        private Logger logger = LoggerFactory.getLogger(getClass());

        @Autowired
        StringRedisTemplate stringRedisTemplate;

        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {

        }

        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
                throws Exception {

        }

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj)
                throws Exception {
            String key = request.getParameter("key");
            if (StringUtils.isEmpty(key)) {
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(JSON.toJSONString(new Result(Error.INCOMPLETE_API_AUTHEN_INFO.getCode(), Error.INCOMPLETE_API_AUTHEN_INFO.getMessage())));
                return false;
            } else {
                logger.info("test redis import :" + stringRedisTemplate.opsForValue().get(key));
                // TODO 驗證邏輯
                return true;
            }
        }

    }
}
技術分享圖片

其中要註意註冊時的區別

registry.addInterceptor(getInterfaceAuthCheckInterceptor()).addPathPatterns("/api/**"); 這種方式無論什麽情況都可以

registry.addInterceptor(new InterfaceAuthCheckInterceptor()).addPathPatterns("/api/**");這種情況時,自定義的interceptor中不能註入其他內容,比如redis或者其他service,如果要註入,必須使用上面這種方法

SpringBoot 攔截器(Interceptor)的使用