讲述代码之前 先插个广告

没错就是我们的知恩电视剧《苦尽柑来遇见你》
image

言归正传 我认为的网关就是"拦截器" 即所有调用 都要经过这里 然后匹配相应的 然后进行转发

当然依旧是三项来介绍 基本上所有都是基于application.properties文件配置:
注意注意 gateway网关也创建为一个项目 即现在三个项目
前言案例:

image

原理参考:

image

一.路由

简单模拟一下

引入依赖:
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
配置文件:
订单服务:
spring.cloud.gateway.routes[2].id=order 路由名字 随便瞎xx起
spring.cloud.gateway.routes[2].uri=lb://nacos-order lb负载均衡记得开启
你的订单服务application.name
商品服务:
spring.cloud.gateway.routes[1].id=product
spring.cloud.gateway.routes[1].uri=lb://nacos-product

启动项目后:

image

已注册到nacos中
image
简单介绍 我们主要搭配Predicates使用


二.断言(Predicates)
配置文件:
spring.cloud.gateway.routes[2].id=order
spring.cloud.gateway.routes[2].uri=lb://nacos-order
这个就是具体到匹配成功后 定位去哪里
这里是/gaooo/** 即订单服务/gaooo下的所有路径
spring.cloud.gateway.routes[2].predicates[0]=Path=/gaooo/**

spring.cloud.gateway.routes[1].id=product
spring.cloud.gateway.routes[1].uri=lb://nacos-product
spring.cloud.gateway.routes[1].predicates[0]=Path=/fanggg/**

使用到这个类PathRoutePredicateFactory

分别在订单和商品的服务controller加上前缀
@RequestMapping("/gaooo")
@RequestMapping("/fanggg")

注意注意:
错误:type=Internal Server Error, status=500
[404] during [GET] to [http://nacos-product/pt/info]
如果你配置了Feign 也需要修改 但不能直接在接口上定义应该:

image
成功访问
image

我们再来模拟一个存在的网页 比如欧冠页面

spring.cloud.gateway.routes[0].id=uefa
spring.cloud.gateway.routes[0].uri=https://www.uefa.com/
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
spring.cloud.gateway.routes[0].order=10

即你输入任何路径 都会跳转到这里 若你不加优先级order的话你之前的也会跳转到这
(order 数字越小 优先级越高) 如不使用则默认按照你创建的来[0] [1] [2]...

image

我们再来个模拟带参数的断言工厂 在使用edge搜索时候(必须带参数)

前面/https://cn.bing.com/ 然后search? 参数 q=你搜索的内容 即跳转
image

这个不难实现:

spring.cloud.gateway.routes[0].id=bing-route
spring.cloud.gateway.routes[0].uri=https://cn.bing.com/
spring.cloud.gateway.routes[0].predicates[0].name=Path
spring.cloud.gateway.routes[0].predicates[0].args.patterns=/search
spring.cloud.gateway.routes[0].predicates[1].name=Query
spring.cloud.gateway.routes[0].predicates[1].args.param=q
spring.cloud.gateway.routes[0].predicates[1].args.regexp=gaoyuan

使用到的就是这个类QueryRoutePredicateFactory

image

再加深一步 就是我们必须在原有的基础上再加上一个自定义的参数
localhost/search?q=gaoyuan&user=fang
引出自定义断言工厂的概念
第一种方式:继承AbstractRoutePredicateFactory实现方法

我们在原有的基础上加上:
spring.cloud.gateway.routes[0].predicates[2].name=VipPredicate
spring.cloud.gateway.routes[0].predicates[2].args.param=user
spring.cloud.gateway.routes[0].predicates[2].args.value=fang
编写配置 必须名字同VipPredicate param 和 value 分别对应
@Component
public class VipPredicate extends AbstractRoutePredicateFactory<VipPredicate.Config> {

    public VipPredicate() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return  new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                ServerHttpRequest request = serverWebExchange.getRequest();
                String first = request.getQueryParams().getFirst(config.param);
                return StringUtils.hasText(first)&&first.equals(config.value);
            }
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("param", "value");
    }

    public static class Config {
        private String param;
        private String value;


        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

不输入后面自定义的参数user=fang 则不会成功
image

输入后
image

第二种方式:JAVA配置类实现

@Configuration
public class VipConfig {
        @Bean
        public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
            return builder.routes()
                    .route("bing-route", r -> r.path("/search")
                            .and()
                            .query("q", "gaoyuan")
                            .and()
                            .query("user", "fang")
                            .uri("https://cn.bing.com/"))
                    .build();
        }
}

当然还有很多 则都是在这个AbstractRoutePredicateFactory类工厂中

image


三.过滤器

在之前订单调用商品服务的时候
我们加入@RequestMapping("/gaooo")
难道以后所有的controller都要加一遍吗
这就是过滤器的作用了 跟之前原理一样 匹配路由后 过滤
我们可以无需再写 它就可以自己带上

spring.cloud.gateway.routes[2].filters[0].name=RewritePath
spring.cloud.gateway.routes[2].filters[0].args.regexp=/gaooo/?(?<segment>.*)
spring.cloud.gateway.routes[2].filters[0].args.replacement=/${segment}

RewritePath这是已有的过滤器 即重写 后面是正则表达式
例如访问 /gaooo/feign/info
/gaooo/?(?.*) 将segment为/feign/info
/${segment} 将匹配到的路径部分替换为 /${segment}即/feign/info
注意注意在product里不能配置 需要在controller上加入@RequestMapping("/fanggg")

将此注解掉

image
访问依旧成功

还有全局过滤器GlobalFilter

参考其机构 重写方法实现

image

当然还有自定义过滤器 实现 和类似自定义断言工厂一样

继承AbstractGatewayFilterFactory类实现方法即可
image

再写个介绍:Actuator监视网关

image

依赖:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
配置文件加入:
management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=*

至于其作用参考:

image

访问http://localhost/actuator/gateway/routes 查看路由关联
image

还有跨域 和 超时 加密等不过多叙述
参考:
过滤器:https://blog.csdn.net/abu935009066/article/details/112261311
跨域:https://blog.csdn.net/chuanchengdabing/article/details/119429659
视频学习:尚硅谷 https://www.bilibili.com/video/BV1UJc2ezEFU/?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=eb2341710c995d8261ecc99fdd066ba7

posted on 2025-03-15 18:55  蒸饺  阅读(1129)  评论(0)    收藏  举报