拦截器和过滤器之间的区别
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调。
过滤器的实现是基于实现Filter接口重写Filter中的init(),doFilter() 以及 ==destory()==方法
在 doFilter() 方法参数中 FilterChain filterChain会以参数的形式传递但下个Filter中去形成了以Filter 为A,doFilter为B的A(B)的函数回调。
@Component
@WebFilter(urlPatterns = "/**")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter...init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter...doFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("Filter...destroy");
}
}
拦截器是基于java的反射机制的 基于springBoot
自定义一个拦截器实现 HandlerInterceptor 接口 并加入到spring容器中
@Component
public class TestIntercept implements HandlerInterceptor {
// 在业务处理器处理请求之前被调用
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
// 在业务处理器处理请求完成之后,生成视图之前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
// 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。基于java-based方式的spring mvc配置,需要创建一个配置类并实现
@Configuration
public class InterceptConfig implements WebMvcConfigurer {
@Autowired
private TestIntercept testIntercept;
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
@Override
public void addFormatters(FormatterRegistry registry) {
}
/**
* @Description:注册一个Interceptor
* @Author: hdh
* @Date: 2021-04-21 11:44
**/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//一个*:只匹配字符,不匹配路径(/)
// 两个**:匹配字符,和路径(/)
//addInterceptor()添加一个自定义拦截器
//addPathPatterns()添加一个拦截路径
//excludePathPatterns() 删除一个拦截路径
//order()优先级 越小优先级越高
registry.addInterceptor(testIntercept).addPathPatterns("/**").pathMatcher();
}
/**
* @Description:自定义资源映射
* @Author: hdh
* @Date: 2021-04-21 11:44
**/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//一个请求图片路径映射到 服务器上
registry.addResourceHandler("/getImg/**").addResourceLocations(":file" + "/home/img");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 拦截所有的请求
.allowedOrigins("*") // 可跨域的域名,可以为 *
.allowCredentials(true)
.allowedMethods("*") // 允许跨域的方法,可以单独配置
.allowedHeaders("*"); // 允许跨域的请求头,可以单独配置
}
/**
* @description:页面跳转 不需要controller 将一个请求跳转到一个页面
* @author:hdh
* @date:2021-04-21 11:48
**/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toLogin").setViewName("login");
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
}
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。