项目示例 - 3.服务网关 - 3.Gateway

项目示例 - 3.服务网关 - 3.Gateway

关联知识:

  • 分布式微服务 - 3.服务网关 - 4.Gateway

内容提要:

  • 基本使用
  • 自定义断言
  • 自定义局部、全局过滤器

基本使用

  1. 建Module:微服务起名为gateway-server
  2. 改pom:引入以下依赖
xml 复制代码
    <dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--Nacos服务注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
  1. 写yml:在resources目录下创建application.yml文件,并做以下配置
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
  1. 主启动:在src下创建如下主启动类
java 复制代码
package learn.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayServer {

    public static void main(String[] args) {
        SpringApplication.run(GatewayServer.class, args);
    }

}
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,浏览器访问localhost/nacos/provider/test 接口,能正常返回信息

自定义断言

  1. 创建自定义断言类:
java 复制代码
package learn.demo.config;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

@Component
public class CustomRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {

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

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

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                List<String> strings = serverWebExchange.getRequest().getHeaders().get(config.key);
                if (strings==null || strings.isEmpty())
                    return false;
                return config.value.equals(strings.get(0));
            }
        };
    }

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

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

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

}
  1. application.yml中配置断言:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息。

自定义过滤器

自定义局部过滤器

  1. 创建自定义过滤器类:
java 复制代码
package learn.demo.config;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {

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

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

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // pre操作
                String pre;
                List<String> strings = exchange.getRequest().getHeaders().get("pre");
                if (strings==null || strings.isEmpty())
                    pre="no args";
                else
                    pre=strings.get(0);

                return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                    // 异步post操作
                    exchange.getResponse().getHeaders().set(config.key, pre+" | "+config.value);
                }));
            }
        };
    }

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

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

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

}
  1. 添加配置:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
          filters:
            - Custom=post,test
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息,查看响应头中有key为post、value为no args | test的参数。

自定义全局过滤器

  1. 创建自定义过滤器类:
java 复制代码
package learn.demo.config;

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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // pre操作
        String pre;
        List<String> strings = exchange.getRequest().getHeaders().get("pre");
        if (strings==null || strings.isEmpty())
            pre="no args";
        else
            pre=strings.get(0);

        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 异步post操作
            exchange.getResponse().getHeaders().set("post", pre+" | test");
        }));
    }

    // 值越小,优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}
  1. 修改配置文件:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息,查看响应头中有key为post、value为no args | test的参数。
相关推荐
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Chrikk5 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*5 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue5 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man5 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
Wx-bishekaifayuan7 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer087 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Yaml48 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理