拦截器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,如果要注入,必须使用上面这种方法