攔截器intercprot 和 過濾器 Filter 其實做用相似java
在最開始接觸java 使用struts2的時候,裏面都是filterweb
後來springmvc時就用interceptorredis
沒太在乎過區別,反正就是起檢查做用的,spring
仔細閱讀 過濾器(filter)和攔截器(interceptor)的區別 後明白了很多json
最重要的要記住他們的執行順序: 先filter 後 interceptorapi
過濾前-攔截前-action執行-攔截後-過濾後mvc
在瞭解上面的信息後,本文講interceptor的使用app
本身定義的interceptor都須要繼承HandlerInterceptor 並實現對應方法preHandle postHandle來實現攔截功能ide
同時須要根據攔截規則進行註冊微服務
實例以下:
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,若是要注入,必須使用上面這種方法