首页 > 其他分享 >过滤器与拦截器

过滤器与拦截器

时间:2023-03-23 15:23:02浏览次数:26  
标签:拦截器 MethodInterceptor Filter 过滤器 注解 拦截

1. 过滤器跟拦截器的区别
在说拦截器之前,不得不说一下过滤器,有时候往往被这两个词搞的头大。

其实我们最先接触的就是过滤器,还记得web.xml中配置的<filter>吗~

你应该知道spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的,如果想要拦截那怎么办?

这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成过滤器中包含拦截器,一个请求过来 ,先进行过滤器处理,看程序是否受理该请求 。
过滤器放过后 , 程序中的拦截器进行处理 。

(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)

(2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预他,通过验证的少点,顺便干点别的东西)。


2. spring中的拦截器
在web开发中,拦截器是经常用到的功能。它可以帮我们验证是否登陆、预先设置数据以及统计方法的执行效率等等。

今天就来详细的谈一下spring中的拦截器。spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor。


2.1 HandlerInterceptor拦截器
HandlerInterceptor是springMVC项目中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行。

实现一个HandlerInterceptor拦截器可以直接实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter类。

这两种方法殊途同归,其实HandlerInterceptorAdapter也就是声明了HandlerInterceptor接口中所有方法的默认实现,而我们在继承他之后只需要重写必要的方法。

注册:
(1)通过spring.xml配置文件注册
拦截器类需要实现HandlerInterceptor接口,并且需要在servlet.xml中配置<mvc:interceptor>
(2)通过配置类进行注册
1.创建我们自己的拦截器类并实现 HandlerInterceptor 接口
2.创建一个Java类添加@Configuration并继承WebMvcConfigurerAdapter或WebMvcConfigurer,并重写 addInterceptors 方法。
3.实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)


2.2 MethodInterceptor拦截器
继承AOP类
MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,即使不是controller中的方法。实现MethodInterceptor拦截器大致也分为两种,
一种是实现MethodInterceptor接口,另一种利用AspectJ的注解或配置。
在invoke()方法中写拦截规则

注册:
(1)通过spring.xml配置文件注册
拦截器类需要实现MethodInterceptor接口,并且需要在.xml中配置<aop:config>,类似于AOP
(2)通过aop的@Aspect注解进行注册
类添加@Aspect注解与@Pointcut()切入点和方法上添加@Before()、@Around()等即可

经测试发现,interceptor先于AOP执行。


3. 谈一谈区别
上面的两种拦截器都能起到拦截的效果,但是他们拦截的目标不一样,实现的机制不同,所以有的时候适用不同的场景。

HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。
当你需要统计请求的响应时间时MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。
MethodInterceptor利用的是AOP的实现机制,在本文中只说明了使用方式,关于原理和机制方面介绍的比较少,
因为要说清楚这些需要讲出AOP的相当一部分内容。在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。

-----------------------------------------------------------------------------------
过滤器

注册方式
(1)@WebFilter(urlpatters="/*")
该类需要实现Filter接口,重写doFilter()方法

在 @WebFilter 注解中可以配置过滤器的拦截规则。这个注解要生效,还需要我们在项目启动类上配置 @ServletComponentScan 注解
@ServletComponentScan 注解虽然名字带了 Servlet,但是实际上它不仅仅可以扫描项目中的 Servlet 容器,也可以扫描 Filter 和 Listener。

这是我们在 Spring Boot 中使用过滤器的第一种方式,在实际项目中,这种方式使用较少,因为这种方式有一个很大的弊端就是无法指定 Filter 的优先级,
如果存在多个 Filter 时,无法通过 @Order 指定优先级。

(2)@Bean
该类需要添加@Component将接口扫描到容器,并实现Filter接口

第二种方式就是将过滤器配置成 Bean,注册到 Spring 容器中去。
这种方法不再需要 @ServletComponentScan 注解,只要一个 Bean 即可
而且这种方式还有一个优势,就是如果存在多个 Filter,可以通过 @Order(-1) 注解指定多个 Filter 的优先级

虽然解决了优先级问题,但是这种方式没有办法设置 Filter 的拦截规则!
是的,直接定义 Bean 的话,默认的拦截规则就是 /* 即拦截所有请求,开发者无法进行自定义配置。

(3)FilterRegistrationBean

第三种方案还是将 Filter 封装成一个 Bean,但这个 Bean 是 FilterRegistrationBean,
通过 FilterRegistrationBean 我们既可以配置 Filter 的优先级,也可以配置 Filter 的拦截规则。
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<Filter> XXXPrecautionFilterRegistrationBean() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.addUrlPatterns(Arrays.asList("/hello/*"));// url拦截规则
filterRegistrationBean.setFilter(new XXXFilter());
filterRegistrationBean.setOrder(-2);
return filterRegistrationBean;
}
}

一般在项目中,我们都是使用 FilterRegistrationBean 来配置过滤器

-----------------------------------------------------------------------------------

AOP切面
@Aspect 就是把一个类定义为切面供容器读取。(类添加@Aspect注解)

@before: 前置通知,在方法执行之前执行。
@After:后置通知,在方法执行后执行。
@AfterReturning: 返回通知,在方法返回结果之后执行。
@AfterThrowing:异常通知,在方法抛出异常之后执行。
@Around:环绕通知,围绕着方法执行。

1.简单实现
@Component
@Aspect
public class TestAspect {
@Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))")
private void log(){
}
@Before("log()")
public void TestBefore(JoinPoint joinPoint){
System.out.println("在调用方法的时候都会调用这个切面");
}
}

2.结合自定义注解实现
#1
@Documented
@Target({ElementType.METHOD}) // 在方法上加
@Retention(RetentionPolicy.RUNTIME) // 运行时
public @interface AnnotationTest {//自定义注解
}
#2
@RequestMapping("/test1")
@AnnotationTest
public String list(@RequestBody Map<String, Object> params){
return "ok";
}
#3
@Pointcut("@annotation(com.atguigu.gulimall.product.annoation.AnnotationTest)")
private void annotation(){

}
@After("annotation()")
public void testAnnotation(){
System.out.println("执行注解注释的方法后执行此方法");
}

标签:拦截器,MethodInterceptor,Filter,过滤器,注解,拦截
From: https://www.cnblogs.com/snad/p/17247580.html

相关文章

  • 爬取的数据,存到mysql中、爬虫和下载中间件、加代理,cookie,header,加入selenium、去重规
    目录0爬取的数据,存到mysql中1爬虫和下载中间件2加代理,cookie,header,加入selenium2.1加代理2.2加cookie,修改请求头,随机生成UserAgent2.3集成selenium3去重规则源码......
  • 布隆过滤器
    本文已收录至Github,推荐阅读......
  • Spring MVC拦截器+注解方式实现防止表单重复提交
    原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。注,如果是集群的方式,则需要将tok......
  • 你学会什么是布隆过滤器了吗?
    导读在对响应时间要求比较严格的情况下,如果我们有里面,那么随着集合中元素数量的增加,我们需要的存储空间越来越大,检索时间也越来越长,导致内存过多开销和时间效率变低。......
  • Redis缓存穿透-布隆过滤器
    Redis缓存穿透-布隆过滤器缓存穿透我举个蘑菇博客中的案例来说,我现在有一个博客详情页,然后博客详情页中的内容假设是存储在Redis中的,然后通过博客的Uid进行获取,正常的情......
  • 过滤器
    过滤器filter<!DOCTYPEhtml><htmllang="en"><!--过滤器,是一个函数,定义到filters节点下,且一定要有return如果全局过滤器和私有过滤器名字一致,此时按照“**就......
  • ASP.NET MVC Filters 4种默认过滤器的使用
    过滤器(Filters)的出现使得我们可以在ASP.NETMVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户,过滤器理论上有以下功......
  • 理解ASP.NET Core - 过滤器(Filters)
    Filter概览如果你是从ASP.NET一路走过来的,那么你一定对过滤器(Filter)不陌生。当然,ASP.NETCore仍然继承了过滤器机制。过滤器运行在过滤器管道中,这是一张官方的图,很好地......
  • JSP显示拦截器的ActionContext内容
    拦截器有:atx.put("login_message","请登陆,再使用系统.");jsp显示message用:Errors:${login_message}。......
  • 前端设计模式——过滤器模式
    前端设计模式中的过滤器模式(FilterPattern)是一种结构型设计模式,它允许我们使用不同的条件来过滤一组对象,并返回符合条件的对象列表。在过滤器模式中,我们有一个包含多个对......