四十九、SpingBoot引入第三方filter

2024-05-10 21:38

本文主要是介绍四十九、SpingBoot引入第三方filter,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近手头活不多,被其他项目拉去帮忙。他们的需求是,项目中需要加入第三方的过滤器(用于单点登录认证的),项目采用的是spring boot,spring boot之前没深入玩过,所以费了些时间。

需求:

    第三方提供了一个filter以及使用标准web.xml时的配置方法,要求整合到项目中

过程:

    第一步:

    作为不百度(google)不会写代码的程序员,第一反应是去baidu一下,毕竟spring boot的使用停留在写web api的码砖水平上。百度结果,大部分都是用类似下面的方法:

    @Beanpublic FilterRegistrationBean pluginFilter(){//将第三方filter实例,配置信息设置到一个FilterRegistrationBean中//详细代码省略,网上到处都是}

    优点在于:简单。

    缺点:这种第三方的filter,如果是多个的,每个都得重新加这种方法,对于扩展来说,啰嗦

 

    于是,寻求spring boot项目直接使用web.xml里过滤器配置的方案,百度了好些,都是直接将spring boot项目变为使用web.xml配置的,这个动作有点大,怕把项目给搞乱了,没敢采用。。。

 

     第二步:

     目标明确为,使用Bean标签返回FilterRegistrationBean(或类似的接口实例)的方向,但是这个Bean要能将多个过滤器注册给spring。稍微读了一下源码,发现FilterRegistrationBean这个鬼,这正起作用的是定义在AbstractFilterRegistrationBean中的方法onStartup方法

public void onStartup(ServletContext servletContext) throws ServletException {Filter filter = this.getFilter();Assert.notNull(filter, "Filter must not be null");String name = this.getOrDeduceName(filter);if (!this.isEnabled()) {this.logger.info("Filter " + name + " was not registered (disabled)");} else { Dynamic added = servletContext.addFilter(name, filter);if (added == null) {this.logger.info("Filter " + name + " was not registered (possibly already registered?)");} else {this.configure(added);}}
}

    所以,咱们重写一下这个onStartup方法(类名后缀用的proxy可能不太合适,请不要在意细节):

package com.xxx.common.filter;import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.boot.web.servlet.FilterRegistrationBean;import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;public class XxxFilterRegistrationBeanProxy extends FilterRegistrationBean{private Document plugin_xml = null;//所有需要注册的filterprivate Map<String,FilterRegistrationBean> filterRegistrationBeans;public IdssFilterRegistrationBeanProxy() {}public Document getPlugin_xml() {return plugin_xml;}public void setPlugin_xml(Document plugin_xml) {this.plugin_xml = plugin_xml;}public IdssFilterRegistrationBeanProxy(Document plugin_xml) throws IllegalAccessException, InstantiationException, ClassNotFoundException {super();this.plugin_xml = plugin_xml;setFilterRegistrationBeans();}@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {if(filterRegistrationBeans == null || filterRegistrationBeans.size()==0) return;//执行实际的FilterRegistrationBean的onStartup方法for(FilterRegistrationBean bean : filterRegistrationBeans.values()){bean.onStartup(servletContext);}}private void setFilterRegistrationBeans() throws ClassNotFoundException, IllegalAccessException, InstantiationException {//读取xml配置文件,实例化FilterRegistrationBeanif(plugin_xml == null) return;filterRegistrationBeans = new HashMap<>();Element root = plugin_xml.getRootElement();Iterator<Element> filter_roots = root.elementIterator("filter");int order = 0;while (filter_roots.hasNext()){order++;Element filter_root = filter_roots.next();String filter_name = filter_root.elementText("filter-name").trim();String class_name = filter_root.elementText("filter-class").trim();Filter filter = (Filter) Class.forName(class_name).newInstance();FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();filterRegistrationBean.setFilter(filter);filterRegistrationBean.setName(filter_name);filterRegistrationBean.setOrder(order);Iterator<Element> parm_settings = filter_root.elementIterator("init-param");while (parm_settings.hasNext()){Element parm = parm_settings.next();filterRegistrationBean.addInitParameter(parm.elementText("param-name").trim(),parm.elementText("param-value").trim());}filterRegistrationBeans.put(filter_name,filterRegistrationBean);}Iterator<Element> filter_mappings = root.elementIterator("filter-mapping");while (filter_mappings.hasNext()){Element filter_mapping = filter_mappings.next();String filter_name = filter_mapping.elementText("filter-name");if(filterRegistrationBeans.containsKey(filter_name)){filterRegistrationBeans.get(filter_name).addUrlPatterns(filter_mapping.elementText("url-pattern"));}}}
}

注入spring boot的单例类中,给出一个Bean注解的方法,返回上面类的实例

package com.xxx.common.filter;import com.xxx.common.utils.PropertyUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStreamReader;@Component
public class XxxPluginFilter {private XxxFilterRegistrationBeanProxy XxxFilterRegistrationBeanProxy = new XxxFilterRegistrationBeanProxy();private Document plugin_xml = null;private final static String plugin_filter_path = PropertyUtil.getProperty("plugin_filter_path");@Beanpublic FilterRegistrationBean pluginFilter(){return XxxFilterRegistrationBeanProxy;}@PostConstructprivate void init() throws IllegalAccessException, InstantiationException, ClassNotFoundException {if(plugin_filter_path == null || plugin_filter_path.isEmpty()) return;SAXReader reader = new SAXReader();InputStreamReader inputStreamReader = null;try {inputStreamReader = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(plugin_filter_path));plugin_xml = reader.read(inputStreamReader);xxxFilterRegistrationBeanProxy = new XxxFilterRegistrationBeanProxy(plugin_xml);} catch (DocumentException e) {e.printStackTrace();} finally {if(inputStreamReader != null) {try {inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}}}}
}

filter的xml配置文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<plugin-filter><filter><filter-name>filter1</filter-name><filter-class>com.test.Filter1</filter-class><init-param><param-name>servername</param-name><param-value>http://localhost:8081</param-value></init-param></filter><filter><filter-name>filter2</filter-name><filter-class>com.test.Filter2</filter-class><init-param><param-name>initteset</param-name><param-value>yyyy</param-value></init-param></filter><filter-mapping><!-- 需要过滤的路径和文件类型 --><filter-name>filter1</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter-mapping><filter-name>filter2</filter-name><url-pattern>/api/*</url-pattern></filter-mapping>
</plugin-filter>

简单粗暴而有效

这篇关于四十九、SpingBoot引入第三方filter的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/977633

相关文章

SpringBoot项目引入token设置方式

《SpringBoot项目引入token设置方式》本文详细介绍了JWT(JSONWebToken)的基本概念、结构、应用场景以及工作原理,通过动手实践,展示了如何在SpringBoot项目中实现JWT... 目录一. 先了解熟悉JWT(jsON Web Token)1. JSON Web Token是什么鬼

如何更优雅地对接第三方API

如何更优雅地对接第三方API 本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程中,有不少场景会对接第三方的API,例如第三方账号登录,第三方服务等等。第三方服务会提供API或者SDK,我依稀记得早些年Maven还没那么广泛使用,通常要对接第三方

SW - 引入第三方dwg图纸后,修改坐标原点

文章目录 SW - 引入第三方dwg图纸后,修改坐标原点概述笔记设置图纸新原点END SW - 引入第三方dwg图纸后,修改坐标原点 概述 在solidworks中引入第三方的dwg格式图纸后,坐标原点大概率都不合适。 全图自动缩放后,引入的图纸离默认的原点位置差很多。 需要自己重新设置原点位置,才能自动缩放后,在工作区中间显示引入的图纸。 笔记 将dwg图纸拖到SW中

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

YOLOv8改进实战 | 注意力篇 | 引入CVPR2024 PKINet 上下文锚点注意力CAAttention

YOLOv8专栏导航:点击此处跳转 前言 YOLOv8 是由 YOLOv5 的发布者 Ultralytics 发布的最新版本的 YOLO。它可用于对象检测、分割、分类任务以及大型数据集的学习,并且可以在包括 CPU 和 GPU 在内的各种硬件上执行。 YOLOv8 是一种尖端的、最先进的 (SOTA) 模型,它建立在以前成功的 YOLO 版本的基础上,并引入了新的功能和改进,以

Hbase Filter+Scan 查询效率优化

Hbase Filter+Scan 查询效率问题 众所周知,Hbase利用filter过滤器查询时候会进行全表扫描,查询效率低下,如果没有二级索引,在项目中很多情况需要利用filter,下面针对这种情况尝试了几种优化的方案,仅供参考,欢迎交流。 根据业务要求,作者需要根据时间范围搜索所需要的数据,所以作者设计的rowKey是以时间戳为起始字符串的。 正确尝试: 1.scan 设置 开始行和结

fetch-event-source 如何通过script全局引入

fetchEventSource源码中导出了两种类型的包cjs和esm。但是有个需求如何在原生是js中通过script标签引呢?需要加上type=module。今天介绍另一种方法 下载源码文件: https://github.com/Azure/fetch-event-source.git 安装: npm install --save-dev webpack webpack-cli ts

Node.js和vue3实现GitHub OAuth第三方登录

Node.js和vue3实现GitHub OAuth第三方登录 前言 第三方登入太常见了,微信,微博,QQ…总有一个你用过。 在开发中,我们希望用户可以通过GitHub账号登录我们的网站,这样用户就不需要注册账号,直接通过GitHub账号登录即可。 效果演示 注册配置 GitHub 应用 1.首先登录你的GitHub然后点击右上角的头像->点击进入Settings页面 2.在

Filter基本原理和使用

https://www.cnblogs.com/xdp-gacl/p/3948353.html 一、Filter简介   Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控

YOLOv8改进 | Conv篇 | YOLOv8引入DWR

1. DWR介绍 1.1  摘要:当前的许多工作直接采用多速率深度扩张卷积从一个输入特征图中同时捕获多尺度上下文信息,从而提高实时语义分割的特征提取效率。 然而,这种设计可能会因为结构和超参数的不合理而导致多尺度上下文信息的访问困难。 为了降低多尺度上下文信息的绘制难度,我们提出了一种高效的多尺度特征提取方法,将原始的单步方法分解为区域残差-语义残差两个步骤。 在该方法中,多速率深度扩张卷积