关键词:
SpringCloud系列之自定义GatewayFilterFactory
学习目的:
- 知道创建一个网关sample
- 知道网关的基本配置
- 知道自定义GatewayFilterFactory类
环境准备:
- JDK 1.8
- SpringBoot2.2.3
- SpringCloud(Hoxton.SR7)
- Maven 3.2+
- 开发工具
- IntelliJ IDEA
- smartGit
新增SpringBoot Initializer项目:New Module->Spring Initializer,选择jdk版本,至少jdk8
packaging选择jar,java version选择jdk8的,然后点next
选择Gateway的依赖,选择之后会自动加上对应pom配置
新建项目之后,检查pom是否有spring-cloud-starter-gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
如果不通过idea的Spring Initializer新建项目的,需要自己加上:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>$spring-cloud.version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
网关配置,业务场景,一个第三方的接口,经过网关路由之后需要在request header里加上一些校验参数
spring:
application:
name: api-gateway # 指定application name
cloud:
gateway:
routes:
- id: get_user_info
uri: http://127.0.0.1:8083
predicates:
- Path=/api/findUser
filters:
- AddRequestHeader=passToken,a68f3eac-5b9c-4fc1-a900-98ee18574576
# FilterFactory名为自定义类名前几个
- name: Custom
args:
passid: 7a11600c-403c-4260-9165-659e138ada9c
serviceId: d8c6ce4c-1b2c-4826-9044-4197d17aad87
自定义一个GatewayFilterFactory,命名后面统一加上GatewayFilterFactory,自定义的字段配在yml的filters.name
package com.example.springcloud.gateway.filter.factories;
import com.example.springcloud.gateway.util.EncryptUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.util.Date;
/**
* <pre>
* 自定义网关过滤器
* </pre>
*
* <pre>
* @author mazq
* 修改记录
* 修改后版本: 修改人: 修改日期: 2021/12/14 09:59 修改内容:
* </pre>
*/
@Slf4j
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config>
implements Ordered
public CustomGatewayFilterFactory()
super(Config.class);
@Override
public GatewayFilter apply(Config config)
return ((exchange, chain) ->
String passToken = exchange.getRequest().getHeaders().getFirst("passToken");
log.info("passToken:" , passToken);
long now = new Date().getTime();
String timestamp = Long.toString((long)Math.floor(now/1000));
String signature = "";
try
signature = EncryptUtils.toSHA256(timestamp + passToken + timestamp);
catch (Exception e)
e.printStackTrace();
log.info("signature:" , signature);
ServerHttpRequest request = exchange.getRequest().mutate()
.header("passid", config.getPassid())
.header("serviceId", config.getServiceId())
.header("signature", signature)
.build();
log.info("passid:" , config.getPassid());
log.info("serviceId:" , config.getServiceId());
return chain.filter(exchange.mutate().request(request).build());
);
@Override
public int getOrder()
return Ordered.HIGHEST_PRECEDENCE;
@Data
public static class Config
private String passid;
private String serviceId;
过滤器将在较早的阶段执行其“pre”逻辑,但稍后会调用它的“post”实现:
官网的图例:首先客户端请求都会先经过Gateway Handler Mapping,匹配上就通过Gateway Web Handler转给过滤器处理,过滤器分为PreFilter(前置过滤器)、PostFilter(后置过滤器)。过滤器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后置”过滤器逻辑
import java.security.MessageDigest;
/**
* <pre>
* 加密工具类
* </pre>
*/
public class EncryptUtils
/**
* sha256签名算法
*/
public static String toSHA256(String str) throws Exception
MessageDigest messageDigest;
String encodeStr = "";
try
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8"));
encodeStr = byte2Hex(messageDigest.digest());
catch (Exception e)
throw e;
return encodeStr;
/**
* byte转换成16进制
*/
protected static String byte2Hex(byte[] bytes)
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++)
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1)
stringBuffer.append("0");
stringBuffer.append(temp);
return stringBuffer.toString();
控制台打印:
signature:72bdd60d2fc6f115eabda1ced766c0c0aa7397521d653977b2fd15d6c6978587
passid:7a11600c-403c-4260-9165-659e138ada9c
serviceId:d8c6ce4c-1b2c-4826-9044-4197d17aad87
然后去第三方接口看请求header参数,可以带过来
注意:如果网关配置不起效,可以尝试设置ordered确定优先级,有多个配置,可以将配置位置适当挪前点
saltstack学习系列之自定义grains
Master端打开存放自定义grains的目录vim/etc/salt/masterfile_roots:base:-/srv/salt/建立自定义模块cd/srv/saltmkdir_grainscd_grains编写自定义grainscatdisk.pyimportosdefdisk():grains={}disk=os.popen(‘fdisk-l|grep‘Disk‘|grep-v‘ 查看详情
cas5.3.1系列之自定义jdbc认证策略
CAS5.3.1系列之自定义JDBC认证策略(三)CAS官方文档是介绍基于配置实现jdbc认证的,可以参考我博客:CAS5.3.1系列之支持JDBC认证登录(二),不过我们也可以通过自定义认证策略的方式实现jdbc认证,pom先加入相关jar<!--CustomAuthen... 查看详情
springboot系列之自定义枚举类的数据校验注解
SpringBoot系列之自定义枚举类的数据校验注解业务场景:数据校验,需要对枚举类型的数据传参,进行数据校验,不能随便传参。拓展,支持多个参数的枚举数据校验在网上找到很多参考资料,所以本博客基于这些博客进行拓展... 查看详情
flutter之自定义按钮raisedbuttonoutlinebuttoniconbutton等——flutter基础系列(代码片段)
RaisedButton(凸起的按钮,其实就是Android中的MaterialDesign风格的Button,继承自MaterialButton)RaisedButton的常用属性属性名称值类型属性值onPressedVoidCallback,一般接收一个方法必填参数,按下按钮时触发的回调,接收... 查看详情
cas5.3.1系列之自定义shiro认证策略(代码片段)
CAS5.3.1系列之自定义Shiro认证策略(四)CAS官方文档是介绍基于配置实现shiro认证的,可以参考官方文档,不过我们也可以通过自定义认证策略的方式实现jdbc认证,pom先加入相关jar<!--CustomAuthentication--><dependency><groupId>... 查看详情
微信小程序之自定义模态弹窗(带动画)实例
...工具的快捷键微信小程序的文件结构——微信小程序教程系列(1)微信小程序的生命周期实例演示——微信小程序教程系列(2)微信小程序的动态修改视图层的数据——微信小程序教程系列(3)微信小程序的新建页面——微信... 查看详情
并发编程系列之自定义可以命名的线程池工厂类(代码片段)
在使用多线程时候,有时候需要记录具体是哪些业务执行的,不过按照默认的情况,是会打印pool-1-thread-1这种类型的数据,所以有时候不能确定具体哪些业务线程执行的,可以先写一个线程池sample类,运行... 查看详情
springboot系列之自定义枚举类的数据校验注解(代码片段)
SpringBoot系列之自定义枚举类的数据校验注解业务场景:数据校验,需要对枚举类型的数据传参,进行数据校验,不能随便传参。拓展,支持多个参数的枚举数据校验在网上找到很多参考资料,所以本博客... 查看详情
pytest之自定义mark(代码片段)
在上一篇Pytest系列文章:Pytest之skip、skipif、xfail,主要介绍pytest中skip、skipif、xfail的用法。以下主要介绍pytest自定义配置及用例运行实战。一个完整的项目,测试用例比较多,比如我们想将某些用例用来做冒烟测... 查看详情
springcloud系列之网关gateway-9.自定义过滤器实现接口计时功能
参考技术A配置过滤器很简单:.filter(timerFilter)最后需要注意一点的是如果我们配置的是局部的过滤器就继承GatewayFilter,如果是全局就继承GlobalFilter,全局过滤器是不需要配置在路由规则中的,因为是全局,所以所有的路由都会... 查看详情
微服务-springcloud学习系列:抽象中间件springcloudstream
1.SpringCloudStream的使用①安装中间件,根据实际需要安装消息中间件(以RabbitMQ为例介绍)②创建服务生成者引入依赖 编写配置编码 执行流程 ③创建服务消费者引入依赖(同生产者一样的依赖)配置 编码 ... 查看详情
springboot之自定义查询query
下面讲解下SpringBoot之自定义查询Query的实例SpringBoot之自定义查询Query有HQL语句查询(Hibernate),还可以采用sql语句本地查询BookDao类查询接口1packagecom.hik.dao;23importjava.util.List;45importorg.springframework.data.jpa.repository.J 查看详情
springcloud系列之apollo配置中心
本篇文章为系列文章,未读第一集的同学请猛戳这里:SpringCloud系列之Apollo配置中心(一)本篇文章讲解Apollo部门管理、用户管理、配置管理、集群管理。点击链接观看:Apollo部门管理、用户管理、配置管理、集群管理视频(获... 查看详情
vue之自定义组件
组件(Component)是我的理解就是自定义元素.(一)自定义组件任何一个以.vue结尾的组件内都可以写自定义组件,一个自定义组件的使用主要2个步骤:1.注册:上代码 2.组件使用 查看详情
spring之自定义事件
编写自定义事件的简单流程如下:(1)编写CustomEvent.javapackagecom.tutorialspoint;importorg.springframework.context.ApplicationEvent;publicclassCustomEventextendsApplicationEvent{publicCustomEvent(Objectsource){super(sou 查看详情
zabbix升级报警之自定义脚本
定义自定义脚本定义客户端支持执行命令定义客户端zabbix-agent进程用户身份可以执行自定义脚本中的命令; 查看详情
xml之自定义参数实体
自定义参数实体就是在普通实体前面加上“%”,其中通过<!ENTITY>声明实体例子如下:DTD文件:对应的XML文件: 查看详情
wpf之自定义滚动条(代码片段)
原文:wpf之自定义滚动条首先我们添加一个带滚动条的textbox控件:<ScrollViewerHeight="130"Width="620"VerticalScrollBarVisibility="Auto"Style="StaticResourcefor_scrollviewer"><TextBlockxml:space="preserve"Name="FtpServe 查看详情