SpringBoot实现过滤器Filter的三种方式

news/2024/10/31 5:29:42/

    • # 实现Filter接口
        • 方式① 使用Filter接口
        • 方式② 使用@Component注解
        • 方式③ Java Config 配置类

# 实现Filter接口

过滤器 Filter 由 Servlet 提供,基于函数回调实现链式对网络请求与响应的拦截与修改。由于基于 Servlet ,其可以对web服务器管理的几乎所有资源进行拦截(JSP、图片文件、HTML 文件、CSS文件等)。

Filter 的生命周期

  • init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,也就是当 Web 容器(tomcat)启动时,调用 init() 方法初始化实例,Filter只会初始化一次。需要设置初始化参数的时候,可以写到init()方法中。
  • doFilter(): 业务处理,拦截要执行的请求,对请求和响应进行处理,一般需要处理的业务操作都在这个方法中实现
  • destroy() : 销毁实例,关闭容器时调用 destroy() 销毁 Filter 的实例。

方式① 使用Filter接口

1、在启动类添加注解@ServletComponentScan ,让 Spring 可以扫描到。
2、通过 @WebFilter 注解,将类声明为 Bean 过滤器类。此时可以指定要拦截的url , 但是不能指定过滤器执行顺序。

@Slf4j
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Resourceprivate RedisTemplate redisTemplate;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;//获取访问 ip 地址String ipAddr = getIpAddr(request);// 存入缓存10s不允许访问String key = new StringBuilder().append("bizKey").append(ipAddr).toString();if (redisTemplate.hasKey(key)) {// 访问次数自增1redisTemplate.opsForValue().increment(key, 1);log.warn("访问过快,存在强刷行为!key={}", key);} else {// 第一次访问redisTemplate.opsForValue().set(key, 1, 10,TimeUnit.SECONDS);}try {filterChain.doFilter(servletRequest, servletResponse);} catch (Exception e) {log.warn("认证失败,e:{},url:{},parameters:{}", e,request.getRequestURL(),request.getParameterMap());servletResponse.setContentType("application/json");servletResponse.setCharacterEncoding("UTF-8");servletResponse.getWriter().write(JSONUtil.toJsonStr(Result.fail("业务执行报错~")));}}@Overridepublic void destroy() {Filter.super.destroy();}public static String getIpAddr(HttpServletRequest request){String ipAddress = null;try {ipAddress = request.getHeader("X-Forwarded-For");if (ipAddress != null && ipAddress.length() != 0 && !"unknown".equalsIgnoreCase(ipAddress)) {// 多次反向代理后会有多个ip值,第一个ip才是真实ipif (ipAddress.indexOf(",") != -1) {ipAddress = ipAddress.split(",")[0];}}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("HTTP_CLIENT_IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}}catch (Exception e) {}return ipAddress;}
}

方式② 使用@Component注解

使用@Component注解后,可以使用@Order注解保证过滤器执行顺序,@Order 注解用于指定组件的执行顺序,其中值越小的组件优先执行。

@Component
@Order(1)
public class MyFilter1 implements Filter {// ...
}
@Component
@Order(2)
public class MyFilter2 implements Filter {// ...
}

注意: 1、不使用@Order注解,则按照filter类名的字母顺序来执行
2、方式②可以保证执行顺序, 但是过滤器不能指定拦截的url , 只能默认拦截全部
在这里插入图片描述

方式③ Java Config 配置类

使用 @Configuration + @Bean 配置类,注解声明Bean,交由 Spring 容器管理。此方式既能拦截Url,也能指定执行顺序
Java Config 的方式可以通过 @Bean 配置顺序或 FilterRegistrationBean.setOrder() 决定 Filter 执行顺序。(在启动类配置拦截器,此时自定义过滤器不加注解,为普通类即可) 可以指定过滤器要拦截的url 和 过滤器执行顺序, 但需要代码方式实现.

public class MyFilter1 implements Filter {// ...
}public class MyFilter2 implements Filter {// ...
}

通过在springboot的configuration中配置不同的FilterRegistrationBean实例,来注册自定义过滤器
这里创建一个configuration类

@Configuration
public class DemoConfiguration {@Beanpublic FilterRegistrationBean RegistTest1(){//通过FilterRegistrationBean实例设置优先级可以生效//通过@WebFilter无效FilterRegistrationBean bean = new FilterRegistrationBean();bean.setFilter(new Test1Filter());//注册自定义过滤器bean.setName("flilter1");//过滤器名称bean.addUrlPatterns("/*");//过滤所有路径bean.setOrder(1);//优先级,最顶级return bean;}@Beanpublic FilterRegistrationBean RegistTest2(){//通过FilterRegistrationBean实例设置优先级可以生效//通过@WebFilter无效FilterRegistrationBean bean = new FilterRegistrationBean();bean.setFilter(new Test2Filter());//注册自定义过滤器bean.setName("flilter2");//过滤器名称bean.addUrlPatterns("/test/*");//过滤所有路径bean.setOrder(6);//优先级,越低越优先return bean;}
}

http://www.ppmy.cn/news/490999.html

相关文章

亚马逊和光环新网破裂_亚马逊推出用于健康和保健的人工智能动力光环带

亚马逊和光环新网破裂 The Halo Band will analyze your tone of voice, determine body composition, and offer feedback on sleep pattern. Halo乐队将分析您的语气,确定身体成分,并提供有关睡眠模式的反馈。 By Matthew Humphries 由 马修汉弗莱斯 …

计算机处理器性能排名,2019电脑cpu处理器性能排名:AMD 32核撕裂者遥遥领先(2)...

在性能TOP20排行榜上,AMD拿下了11个席位,领先Intel两席,而且轻松拿下冠军,32核心64线程的撕裂者2990WX得分高达45万,领先第二名18核心36线程的酷睿i9-9980XE多达25%。 Intel上代旗舰18核心36线程的酷睿i9-7980XE紧随其…

计算机处理器份额,处理器市场份额排名 英特尔X86架构继续领先

由于苹果iPad平板电脑的崛起,关于其采用的ARM架购处理器引起了人们的普遍关注,虽然ARM在智能手机领域以及一些嵌入式系统中,有着良好的表现,但是其市场分额短时间内还是没有办法和英特尔为代表的X86架构处理器相抗衡。据Mercury R…

cpu排行计算机专业,最新计算机处理器排名_cpu性能排名梯形图高清大图

当我们购买或组装电脑时,无论是台式电脑还是笔记本电脑,我们都需要选择一款处理器性能优异且符合我们自身预算的中央处理器。只有当处理器的性能达到时,其他设备的优势才能得到充分体现。目前,英特尔和AMD的设备更新很快&#xff…

微型计算机 2018 12月下,桌面CPU天梯图2018年12月最新版 十二月台式电脑处理器排名...

时光飞逝,转眼2018还有不到一个月就要划上一个完美句号了。年底将近,近期DIY装机的小伙伴也开始多了起来了。今天小编按照惯例,带来一月一更的台式电脑CPU天梯图更新,希望大家会喜欢。CPU作为电脑的“大脑”,是最核心的…

企业级大数据平台建设参考 淘宝滴滴美团360快手京东

大数据平台是为了计算,现今社会所产生的越来越大的数据量,以存储、运算、展现作为目的的平台。大数据技术是指从各种各样类型的数据中,快速获得有价值信息的能力。适用于大数据的技术,包括大规模并行处理(MPP&#xff…

esxi 安装网卡驱动

公司HPE 360 gen8 购买了一个SFN6122F 网卡 在ESXI上面看不见 到官方查找了对应版本的驱动 VMware Compatibility Guide - I/O Device Search 查找结果是该网卡最高支持到6.7U3所以如果是7的版本该网卡就不支持了。 下载对应版本。 安装驱动: 开启ESXI 的ssh服务…

kali安装网卡驱动

安装过程真心不容易!! 我的网卡8812au和wdn6200 8812au驱动github:https://github.com/morrownr/8812au-20210629 修改源,注释第三方源,第三方反而不行我丢sudo vim /etc/apt/sources.list添加以下官方源 deb http://…