使用Gateway的时候,时长会有一些需求,要放在Gateway中去处理,如果一些登陆校验,权限校验之类的,从而降低一些应用服务器的压力。这个时候就需要在Gateway项目中自定义Filte去处理。

步骤

创建自定义filter的步骤

  1. 创建XxxGatewayFilterFactory,继承AbstractGatewayFilterFactory,如CheckLoginGatewayFilterFactory,必须以GatewayFilterFactory为结尾

  2. 重写apply方法

  3. 通过@Bean的方式将自定义的Filter添加到spring容器中,在类上加@Service的方式无法添加

  4. 在配置中引入自定义Filter,名称为XxxGatewayFilterFactory中的Xxx,如CheckLogin,

  5. 如果需要增加一些配置,用于Filter的逻辑判断,如官方的PrefixPathGatewayFilte中可以配置prefilx的值,那么可以在当前类创建一个静态内部类,然后声明在类上,如

public class RejectUrlGatewayFilterFactory extends AbstractBaseCheckGatewayFilterFactory<RejectUrlGatewayFilterFactory.Config>
  1. 写入到配置文件中,由于我们不引入Order,所以默认我们写的自定义Filter的Order都是0,引入多个filter时,执行顺序按配置的顺序执行

示例

普通的自定义filter

比如校验请求的header中是否包含必须的自定义的参数

创建CheckHeaderParamGatewayFilterFactory,然后创建一个Config,用来配置需要被校验的header,

然后继承AbstractGatewayFilterFactory,重写applay方法,apply方法中的Config参数就是我们自己定义的Config

public class CheckHeaderParamGatewayFilterFactory extends AbstractGatewayFilterFactory<CheckHeaderParamGatewayFilterFactory.Config> {@Overridepublic GatewayFilter apply(Config config) {return null;}@Datapublic static class Config {/*** 要校验的header的key,用逗号分隔*/private String header;}
}

编写处理逻辑

@Slf4j
public class CheckHeaderParamGatewayFilterFactory extends AbstractGatewayFilterFactory<CheckHeaderParamGatewayFilterFactory.Config> {private final ObjectMapper objectMapper = new ObjectMapper();@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {String[] checkHeaderArr = getCheckHeaderArr(config);// 没有配置,进入下一个filterif (checkHeaderArr == null){log.info("check header config is null");return chain.filter(exchange);}log.info("requestUri:【{}】 校验 header", exchange.getRequest().getURI().toString());// 获取请求的所有headerHttpHeaders headers = exchange.getRequest().getHeaders();for (String headerName : checkHeaderArr) {if (StringUtils.isBlank(headerName)){continue;}// 如果要被校验的header不存在,直接编写响应信息给接口调用方if (!headers.containsKey(headerName)) {return writeParamErrorResponse(exchange, headerName + "不能为空");}}log.info("requestUri:【{}】 校验 header 通过", exchange.getRequest().getURI().toString());// 校验通过,进入下一个filterreturn chain.filter(exchange);};}/*** 处理失败时的返回*/private Mono<Void> writeParamErrorResponse(ServerWebExchange exchange, String message) {ApiResponse<Void> response = new ApiResponse<>();response.setResultCode("PA_PARAM_ERROR");response.setMessage(message);return writeErrorResponse(exchange, response);}/*** 处理失败时的返回*/private Mono<Void> writeErrorResponse(ServerWebExchange exchange, Object responseBody) {ServerHttpResponse response = exchange.getResponse();response.getHeaders().setContentType(MediaType.APPLICATION_JSON);response.setStatusCode(HttpStatus.OK);return response.writeWith(Mono.fromSupplier(() -> {DataBufferFactory bufferFactory = response.bufferFactory();try {log.info("校验失败:{}", responseBody);return bufferFactory.wrap(objectMapper.writeValueAsBytes(responseBody));} catch (JsonProcessingException e) {log.error("json转换异常", e);return bufferFactory.wrap(new byte[0]);}}));}/*** 从Config中获取配置*/private String[] getCheckHeaderArr(Config config) {String[] checkHeaderArr;String header = config.getHeader();if (StringUtils.isBlank(header)) {checkHeaderArr = null;} else {checkHeaderArr = header.split(",");}return checkHeaderArr;}@Datapublic static class Config {/*** 要校验的header的key,用逗号分隔*/private String header;}
}

将filter注册到Spring容器中

@Configuration
public class GatewayFilterConfig {@Beanpublic CheckHeaderParamGatewayFilterFactory checkHeaderParamGatewayFilterFactory(){return new CheckHeaderParamGatewayFilterFactory();}
}

在配置文件中配置的模式

yaml

filters:- CheckHeaderParam=token,visitorId

本人项目中采用在nacos中通过json的模式进行动态路由的配置,json中的对应格式为

"filters": [{"name": "CheckHeaderParam","args":{"header":"token,visitorId"}}
]

继承了Spring中某些特殊filter

比如某些场景下,我们需要对某个路由中的响应做数据类型转换,这个时候,可以直接继承Spring的ModifyResponseBodyGatewayFilterFactory

@Slf4j
public class ConvertBankResponseGatewayFilterFactory extends ModifyResponseBodyGatewayFilterFactory {public ConvertBankResponseGatewayFilterFactory(List<HttpMessageReader<?>> messageReaders, Set<MessageBodyDecoder> messageBodyDecoders, Set<MessageBodyEncoder> messageBodyEncoders) {super(messageReaders, messageBodyDecoders, messageBodyEncoders);}@Autowiredprivate BankCodeMappingConfig bankCodeMappingConfig;@Overridepublic GatewayFilter apply(Config config) {// 创建一个新的ConfigConfig conf = new Config();// 处理类型转换conf.setRewriteFunction(BankResponse.class, ApiResponse.class,(serverWebExchange, response) -> {Optional<BankResponse> resp = Optional.ofNullable(response);ApiResponse<Object> apiResponse = new ApiResponse<>();apiResponse.setBody(resp.map(BankResponse::getData).orElse(null));apiResponse.setResultCode(resp.map(BankResponse::getCode).map(e->bankCodeMappingConfig.getCodeMapping(e)).orElse(StringUtils.EMPTY));apiResponse.setMessage(resp.map(BankResponse::getMsg).orElse(StringUtils.EMPTY));log.info("BankResponse:【{}】, ApiResponse:【{}】",response,apiResponse);return Mono.just(apiResponse);});// 将新创建的config传入return super.apply(conf);}
}

添加到Spring容器

@Bean
public ConvertBankResponseGatewayFilterFactory convertBankResponseGatewayFilterFactory(ServerCodecConfigurer codecConfigurer, Set<MessageBodyDecoder> bodyDecoders,Set<MessageBodyEncoder> bodyEncoders) {return new ConvertBankResponseGatewayFilterFactory(codecConfigurer.getReaders(), bodyDecoders, bodyEncoders);
}

在配置文件中配置的模式

yaml

filters:- ConvertBankResponse

json

"filters": [{"name": "ConvertBankResponse"}
]

SpringCloudGateway自定义Filter相关推荐

  1. Spring Security 入门(四):自定义-Filter

    前文导读 - Spring Security入门(一):登录与退出 - Spring Security入门(二):基于数据库验证 - Spring Security入门(三):密码加密 本文解决问题 ...

  2. 【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener

    =================6.SpringBoot拦截器实战和 Servlet3.0自定义Filter.Listener ============ 1.深入SpringBoot2.x过滤器Fi ...

  3. java filter 注解_Spring常用注解及自定义Filter的实现

    @Configuration通常用在配置类上,告诉spring这是一个配置类(配置类类似配置文件,区别在于用类的形式来表现xml: @Service用于标注业务层组件service层, @Contro ...

  4. Django(模板语言-自定义filter和simple_tag)

    filter过滤器的主要形式:变量|函数,意思是将变量交给函数处理,而自定义filter就是自己定义函数,因为用到已有的很少. 1.在当前app中创建templatetags模块(包:带__init_ ...

  5. Spring-Security 自定义Filter完成验证码校验

    Spring-Security的功能主要是由一堆Filter构成过滤器链来实现,每个Filter都会完成自己的一部分工作.我今天要做的是对UsernamePasswordAuthenticationF ...

  6. java自定义 filter,HBase自定义Filter

    必需要提前说明下:不建议使用自定义的Filter.所有的Filter都是在服务端生效:就是说需要将自定义的Filter封装为jar,上传到HBase的类路径下,并重启HBase使之生效.对于生产环境的 ...

  7. SpringBoot自定义Filter

    SpringBoot自定义Filter SpringBoot自动添加了OrderedCharacterEncodingFilter和HiddenHttpMethodFilter,当然我们可以自定 义F ...

  8. Python框架篇之Django(Template模版:标签tag、自定义filter、extend模板继承)

    文章目录 一.标签的使用(tag) 二.自定义filter和simple_tag 三.extend模板继承 一.标签的使用(tag) 1.语法格式:{% tags %} 2.提供的几种标签 {% if ...

  9. Python学习(三十七)—— 模板语言之自定义filter和中间件

    一.模板语言之自定义filter 自定义filter文件存放位置 模板中自定义函数- 在已注册的app中创建一个名字叫 templatetags 文件夹- 任意创建一个py文件- 创建名字交 regi ...

最新文章

  1. 类型参数的约束(C# 编程指南)
  2. 分布式技术比较(RPC,CORBA,WebService)
  3. 《他其实没那么喜欢你》经典台词
  4. Hadoop_计算框架MapReduce
  5. hadoop--Map Join
  6. 文件系统04 - 零基础入门学习Delphi37
  7. 【BCS2021】软件供应链完整演讲回看
  8. 用@Scheduled完成定时任务
  9. 《计算机组成原理》唐朔飞第三版知识点总结
  10. CellCtrl控件完美破解研究
  11. 折叠屏要来了,适配逼死 Android 开发?谷歌有办法!
  12. Dynamic Web TWAIN:网页扫描过程中如何自动检测和删除空白页?
  13. 两个9014三极管简易开关电路分析
  14. springboot 解决 woff2、ttf 跨域无法解析问题
  15. 信息系统开发方法-生命周期法
  16. BC20 MQTT与GPS功能测试
  17. BlumNet: Graph Component Detection for Object Skeleton Extraction阅读笔记
  18. JAVA SM2 数字证书生成
  19. flash控件使用手册
  20. Linux进程亲族关系图

热门文章

  1. 【第一篇】学习与奋斗,不努力就会与社会脱节
  2. uni.app小程序实现跳转获取数据
  3. 已解决nltk.download(‘punkt’) [nltk_data] Error loading punkt: [WinError 10060] [nltk_data]
  4. html制作在线视频音乐播放器,用html5制作音乐播放器,这3款就足够了!
  5. 广东教国笔怎样才能提高自制力!
  6. python爬虫天气
  7. Android 开发小仓库
  8. PR2019 (二)比较基本
  9. PyCharm使用教程:选择性忽略 PEP8 警告
  10. 4面字节跳动拿到2-2-Offer,入职就是30K16薪,全靠这份Android知识点PDF大全