SpringMVC:( 过滤器和拦截器 )详解
1. 图解
在请求到达容器前,进入Filter过滤器链,执行完过滤器链上每个Filter.doFilter()方法后,进入Servlet.service()方法,然后由dispatcher分发器将请求方法给对应映射成功的处理器controller,在进入controller具体方法之前,会被先进入Interceptor.preHandler()方法,然后再进入controller的具体返回,执行之后进入Interceptor.postHandler()这里主要是拦截了controller方法执行之后到返回的数据模型到达视图解析器之前,接着进入Interceptor.afterCompletion()方法,主要可以操作返回客户端之前的逻辑,最后返回到过滤链中各个Filter的调用点,可以处理返回到客户端的跳转等逻辑。
2. 什么是过滤器(Filter)
过滤器:
过滤器拦截的是request请求,有初始化方法和销毁方法,拦截的是Request、Response请求,粒度很大。
过滤器实现Filter接口并提供了三个方法,分别是初始化(init)方法,具体拦截函数(dofilter)方法和销毁(destroy)方法,过滤器随着容器的启动和销毁而初始化和销毁,依赖于servlet容器,
过滤器拦截的是请求地址(Request、Response)请求,过滤器运行在servlet操作之前,比如对请求参数进行校验,或者设置、检验头部信息,再或者对一些非法行为进行校验。
具体代码实现
package com.example.demo.modules.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* @Description:
* @date : 2022/9/26
*/
public class MyFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
System.out.println("过滤器销毁方法");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("过滤器具体对请求的操作, 比如验证Token,权限,路径等");
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("过滤器初始化方法");
}
}
package com.example.demo.modules.filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
/**
* 创建过滤器myFilter,并且添加到FilterRegistrationBean
* 注入到IOC中
* @Description:
* @date : 2022/9/26
*/
@Configuration
public class ConfigBean {
// 把自定义的过滤器类加入过滤器链中
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
// 将自定义过滤器加入到过滤器链中
filterRegistrationBean.setFilter(myFilter());
// 自定义命名
filterRegistrationBean.setName("myFilter");
// 过滤的路径 /*:全部
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
// 注入到IOC容器中
@Bean
public Filter myFilter(){
return new MyFilter();
}
}
3. 什么是拦截器(Interceptor)
拦截器:
拦截器基于Java的jdk动态代实现的,由HandlerInterceptor接口实现,由于是spring容器的接口,所以它是依赖于spring容器,并不依赖于servlet容器。
拦截器的原理是AOP的思想,可以对某一个方法进行横切,做一些业务逻辑。主要针对于contraller方法,它能获取到所有的类,对类里面所有的方法实现拦截,粒度更小。
具体代码实现
package com.example.demo.modules.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Description:
* @date : 2022/9/26
*/
@Slf4j
public class CustomHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
log.info("Request请求调用之前");
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
log.info("Request请求调用之后");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
log.info("afterCompletion:请求调用完成后回调方法,即在视图渲染完成后回调");
}
}
package com.example.demo.modules.interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Description:
* @date : 2022/9/26
*/
@Configuration
public class WebConfig extends WebMvcConfigurer {
// 添加自定义拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
// 拦截路径 /*:全部
registry.addInterceptor(getHandlerInterceptor()).addPathPatterns("/*");
}
// 注入到IOC
@Bean
public static HandlerInterceptor getHandlerInterceptor(){
return new CustomHandlerInterceptor();
}
}
4. 小结
过滤器是servlet中的接口,主要可以用于在请求进入到servlet之前拦截请求HttpServletRequest并根据需要进行一些检查等逻辑操作,也可以在HttpServletResponse返回到客户端之前进行一些逻辑操作。
拦截器是spring中的接口,所以它可以获取到spring中的一些bean和其他的一些资源,在面向切面编程中应用比较广,拦截其实就是一种AOP策略。
文章整合至:https://blog.csdn.net/weixin_44253023/article/details/121940932、https://blog.csdn.net/huyiju/article/details/83028720、https://blog.csdn.net/csdnjiamin/article/details/109523151