【SpringCloud】十、Spring Cloud Gateway自定义谓词-自定义过滤器

上一篇:【SpringCloud】九、Spring Cloud Gateway的基础介绍

一、Spring Cloud Gateway内部流程源码分析

(1)根据自动装配spring-cloud-gateway-core.jar的spring.factories;
(2)GatewayClassPathWarningAutoConfiguration检查前端控制器;
(3)网关自动配置GatewayAutoConfiguration;
(4)RoutePredicateHandlerMapping.getHandlerInternal(…)获取Route;
(5)执行FilteringWebHandler

二、Spring Cloud Gateway自定义谓词

Spring Cloud Gateway内置了一系列的路由谓词工厂,但是如果这些内置的路由谓词工厂不能满足业务需求的话,可以自定义路由谓词工厂来实现特定的需求;
下面列举两个例子:
1、要求请求必须携带一个token,并且token值等于指定的值,才能访问;
2、要求某个服务的用户只允许在23:00 - 6:00这个时间段内才可以访问;

1、自定义谓词具体步骤:

  • (1)首先定义一个配置类,用于承载配置参数;
  • (2)定义一个路由谓词工厂;
  • 注:TokenRoutePredicateFactory类,前面的Token与.yml配置文件里面配置的名字对应,后面的RoutePredicateFactory名字是固定的,不能随便写,这是Spring Cloud Gateway的约定,类名须为“谓词工厂名(比如:Token)” + RoutePredicateFactory
  • (3)在配置文件中启用该路由谓词工厂,即配置一个Token=123456;

时间格式不是随便配置,而是Spring Cloud Gateway的默认时间格式,采用JDK8里面的格式化:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
String nowTime = dateTimeFormatter.format(ZonedDateTime.now());
System.out.println(nowTime);

到此为止就实现了一个自定义路由谓词工厂,若此时token值不相等,不在允许的访问时间段内,访问就会报404;

2、Spring Cloud Gateway谓词不匹配404处理

处理的顶层接口是WebExceptionHandler
默认实现是DefaultErrorWebExceptionHandler
在这里插入图片描述
我们需要覆盖它的默认实现DefaultErrorWebExceptionHandler,覆盖里面的方法,在方法里面编写我们想要返回的结果,参看我们git代码;

三 、Spring Cloud Gateway自定义路由过滤器

网关过滤器的顶层接口是GatewayFilterFactory
通常情况下可以继承AbstractGatewayFilterFactory实现自定义网关过滤器;
或者继承AbstractNameValueGatewayFilterFactory,该方式配置方式更简单,然后覆盖里面的一个方法,具体参考一下我们的样例代码,实际上理解流程思路即可,真正需要做的时候,查一下就可以;

1、Spring Cloud Gateway全局过滤器

在这里插入图片描述
上面的过滤器工厂是执行在指定路由之上,可以称为路由过滤器(或者局部过滤器),而全局过滤器是作用于所有的路由上,对所有的路由进行过滤;
全局过滤器的顶层接口是GlobalFilter ,和GatewayFilter 有一样的接口定义,只不过GlobalFilter 会作用于所有路由;

全局过滤器有执行顺序问题,通过getOrder()方法的返回值决定执行顺序,数值越小越靠前执行;
Spring cloud gateway默认内置了很多全局过滤器,比如:

  1. Combined Global Filter and GatewayFilter Ordering
  2. Forward Routing Filter
  3. The LoadBalancerClient Filter
  4. The ReactiveLoadBalancerClientFilter
  5. The Netty Routing Filter
  6. The Netty Write Response Filter
  7. The RouteToRequestUrl Filter
  8. The Websocket Routing Filter
  9. The Gateway Metrics Filter
  10. Marking An Exchange As Routed

2、自定义全局过滤器示例

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 自定义全局Filter
 *
 */
@Slf4j
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("全局Filter请求......");

        MultiValueMap<String, String> valueMap = exchange.getRequest().getQueryParams();
        valueMap.forEach((k, v) -> {
            log.info("全局Filter拦截参数 {} ", k);
            v.forEach(s -> {
                log.info("全局Filter拦截参数值 = {} ", s);
            });
        });
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

四 、Spring Cloud Gateway集成ribbon负载均衡

实现原理是在全局LoadBalancerClientFilter中进行拦截,然后再该过滤器中依赖LoadBalancerClient loadBalancer,而此负载均衡接口的具体实现是RibbonLoadBalancerClient,即spring cloud gateway已经整合好了ribbon,已经可以实现负载均衡,我们不需要做任何工作,网关对后端微服务的转发就已经具有负载均衡功能;

五 、Spring cloud gateway跨域CORS

我们知道,传统的Ajax请求只能获取在同一个域名下的资源,但是HTML5规范中打破了这种限制,允许Ajax发起跨域的请求;(只是需要设置一下)
其实浏览器本身是可以发起跨域请求的,比如你可以链接一个另一个域名下的图片或者js,比如,但是javascript脚本是不能获取这些另一个域名下的资源内容的;
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),它允许浏览器向跨域的另一台服务器发出XMLHttpRequest请求,从而克服了AJAX只能访问同域名下的资源的限制;
这种CORS使用了一个额外的HTTP响应头来赋予当前user-agent(浏览器)获得跨域资源的权限,这里的跨域也就是Cross-Origin的概念,这里的权限就是访问另一个域名下的资源权限;
CORS是现在HTML5标准中的一部分,在大部分现代浏览器中都有所支持,可能在某些老版本的浏览器不支持CORS,如果要兼容一些老的浏览器版本,则需要采用JSONP进行跨域请求;

同源与非同源的定义(跨域和不跨域)

如果 访问协议、端口(如果指定了端口的话)、host都相同,则称之为同源(不跨域),否则为非同源(跨域);
比如源链接: http://store.company.com/dir/page.html

在这里插入图片描述

Spring Cloud Gateway解决跨域问题,只需要配置如下代码即可:

/**
 * 配置网关跨域cors请求支持
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new 
UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍 【完善体系+精品资料】本课程总计115课时,打造全网最全的微服务体系课程;从微服务是什么、能够做什么开始讲起,绝对零基础入门到精通类型。课程整体脉络分清晰,每个章节一个知识点,画图+源码+运行讲解,不信你学不会。1、课程先讲解了什么是单体架构、什么是微服务架构、他们之间有什么区别和联系,各自有什么优缺点。2、从本质入手,使用最简单的Spring Boot搭建微服务,让你认清微服务是一种思想和解决问题的手段,而不是新兴技术。3、讲解Spring Boot 与 Spring Cloud 微服务架构之间的联系,原生的RestTemplate工具,以及Actuator监控端点的使用。4、带着微服务所带来的各种优缺点,为大家引入服务发现与注册的概念和原理,从而引入我们的第一个注册中心服务Eureka。5、引入负载均衡的理念,区分什么是服务端负载均衡,什么是客户端负载均衡,进而引入Ribbon负载均衡组件的详细使用。6、为了解决微服务之间复杂的调用,降低代码的复杂度,我们引入了Feign声明式客户端,让你几行代码学习服务的远程调用。7、为了解决服务之间的稳定性,避免发生雪崩问题,我们引入了Hystrix断路器,服务降级和熔断机制。8、微服务集群分庞大,监控起来是分困难的,尤其是对每一个接口的熔断情况进行监控,因此我们引入了Turbine微服务监控。9、微服务的调用是杂乱无章的,可以网状调用,怎么做到统一的入口出口,统一的授权、加密、解密、日志过滤,我们引入了第一代网关Zuul。10、微服务的配置分散,每次要修改配置都要重启服务,因此我们引入了Config配置中心。11、跟上主流,Consul是当前主流的服务注册与发现、配置中心一体化的解决方案。12、阿里的Nacos服务注册与发现、配置中心在国内炙手可热,Nacos 经历过双一的微服务中间件。13、Turbin做微服务监控还是太弱,我们需要更强大,可视化,操作性更强的监控系统,因此我引入了Spring Boot Admin体系。14、Zuul已经停止更新支持,Spring Cloud官方推荐的二代网关Spring Cloud Gateway更加强大。15、微服务的安全架构体系虽然复杂,但是是有学习条例的,什么是认证授权、什么是OAuth2.0的原理、 JWT、怎么样去开发实现。 课程资料 【独家资料】1、课程附带全部63个项目源码,其中Hoxton版本项目源码37个,Edgware版本项目26个,2、230页高清PDF正版课件。3、附带nacos、consul、cmder等视频配套软件。学习方法1、每一节课程均有代码,较好的方式为一边听我的讲解,一边使用我提供的项目代码进行观察和运行。2、课程体系庞大,但是并不杂乱,每个章节只针对一个知识点,减轻学习压力。3、坚持每天学习1~2个章节,可以在地铁、公交上用手机学习。【完善知识体系图】

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值