Filter、Interceptor的使用
一、Filter、Interceptor的区别
1.1、过滤器(Filter)
它依赖于servlet容器。它可以对几乎所有请求进行过滤。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。
通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。
1.2、拦截器(Interceptor)
它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制。
属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。
二、Filter、Interceptor的使用
2.1、Filter 的实现步骤
1、创建一个类,实现 Filter 接口,重写抽象方法
2、类上标记@WebFilter(“要拦截的资源”)
3、引导类标记@ServletComponentScan
@WebFilter(urlPatterns = {"/depts"})
public class MyFilter implements Filter {
/**
* 初始化
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter======>初始化操作~~~~~~");
}
/**
* 拦截操作
* */
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行前执行的业务逻辑
System.out.println("MyFilter======>校验参数~~~~~~");
System.out.println("MyFilter======>参数校验成功放行~~~~~~~~~");
// 放行方法
filterChain.doFilter(servletRequest,servletResponse);
//放行后执行的业务逻辑
System.out.println("MyFilter======>执行 doFilter 方法成功~~~~~~~~~");
}
/**
* 销毁
* */
@Override
public void destroy() {
System.out.println("MyFilter======>销毁操作~~~~~~~");
}
}
2.2、Interception 结合JWT 的实现步骤
1、创建一个类,实现 HandlerInterceptor
2、类上标记 @Component 注解,注入到容器中
3、注册拦截器
3.1、创建一个配置类,实现 WebMvcConfigurer
3.2、重写 addInterceptors 方法,增加拦截器并编写拦截规则
3.3、注册拦截器
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
/**
* @description 在Handler执行之前执行,一般用于权限控制
* @Author Wangp
* @date 14:18 2023/4/11
* @param request
* @param response
* @param handler
* @return boolean
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1.获取请求路径
String uri = request.getRequestURI();
StringBuffer url = request.getRequestURL();
log.info("获取的请求地址uri======>{},url=========>{}",uri,url);
response.setContentType("application/json;charset=UTF-8");
ObjectMapper objectMapper = new ObjectMapper();
// 2.获取 校验参数 (token)
String token = request.getHeader("token");
log.info("获取的token是======》{}",token);
if (token == null || "".equals(token)) {
Result result = Result.error("NOT_LOGIN");
String resultJson = objectMapper.writeValueAsString(result);
log.info("result=========>{}",result);
response.getWriter().write(resultJson);
return false;
}
// 4.解析 jwt令牌
try {
JwtUtils.parseJWT(token);
} catch (Exception e) {
e.printStackTrace();
Result result = Result.error("NOT_LOGIN");
String resultJson = objectMapper.writeValueAsString(result);
log.info("resultJson==============>",result);
response.getWriter().write(resultJson);
return false;
}
// 5.放行
return true;
}
/**
* @description 在Handler执行之后,渲染视图之前执行
* @Author Wangp
* @date 14:19 2023/4/11
* @param request
* @param response
* @param handler
* @param modelAndView
* @return void
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("在Handler执行之后,渲染视图之前执行");
}
/**
* @description 所有操作结束之后执行,一般用于释放资源
* @Author Wangp
* @date 14:19 2023/4/11
* @param request
* @param response
* @param handler
* @param ex
* @return void
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("所有操作结束之后执行,一般用于释放资源");
}
}
@Configuration
public class LoginConfigurer implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
}
}
三、Filter、Interception详解
3.1、Filter 详解
init 初始化方法只会执行一次,Tomcat启动时,创建Filter时,init执行了
destory销毁方法只会执行一次,Tomcat停止时,销毁Filter时,destory执行
doFilter过滤方法拦截到一个请求就执行一次,拦截资源根据需求做处理
1、执行流程
2、拦截路径配置
3、过滤器链:过滤器链的执行顺序按过滤器类名进行排序
3.2、Interception详解
1、拦截路径
2、执行流程:请求先过滤器,再到拦截器,再到Handler。响应时,先到拦截器,再到过滤器