当前位置: 首页 > backend >正文

Spring Cloud Gateway 网关(五)

目录

一 概念引入

二 具体使用

1 首先创建一个网关模块

2 启动类

3 配置类

4 对应方法的修改

5 展示借助81端口进行转发控制

6 断言规则​编辑

三 过滤器

1 将前置的请求参数给过滤掉,降低繁琐程度。

2 默认过滤器

3 全局过滤器

4 自定义过滤器工厂

5 全局跨域问题


一 概念引入

Spring Cloud Gateway :: Spring Cloud Gateway

二 具体使用

1 当前主流更多使用的是Reactive Server ,而ServerMVC是老版本的网关。

前景引入:

LoadBalancer:服务内部调用时的负载均衡。

Gateway 负载均衡:系统对外统一入口的负载均衡,内部也会用 LoadBalancer。

        <!--   添加nacos注册中心     --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--   添加网关的依赖     --><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>

实现:

1 首先创建一个网关模块

2 启动类

package com.ax.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient
@SpringBootApplication
public class GatewayMainApplication {public static void main(String[] args) {SpringApplication.run(GatewayMainApplication.class, args);}
}

3 配置类

借助的就是81端口的网关进行映射

spring:profiles:include: routeapplication:name: gatewaycloud:nacos:server-addr: 127.0.0.1:8848
server:port: 81
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-orderpredicates:- Path=/api/order/**- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**- id: last-routeuri: https://cn.bing.com/predicates:- Path=/**

4 对应方法的修改

需要以规范的格式开头(加上api/order或者api/product)

package com.ax.product.controller;import com.ax.product.bean.Product;
import com.ax.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;@Slf4j
@RequestMapping("/api/product")
@RestController
public class ProductController {@Autowiredprivate ProductService productService;// 获取商品信息@GetMapping("/product/{id}")public Product getProduct(@PathVariable("id") Long id) {log.info("getProduct:{}", id);return productService.getProductById(id);}
}

对应的远程调用,这里有一个语法版本兼容问题不能在类的头部写@RequestMapping

package com.ax.order.feign;import com.ax.order.feign.fallback.ProductFeignClientFallback;
import com.ax.product.bean.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@FeignClient(name = "service-product", fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {/*** 测试FeignClient** @param id*///mvc注解两套使用逻辑//标注在Controller上,为接收请求//标注在FeignClient上,为发送请求@GetMapping("/api/product/product/{id}")Product getProductById(@PathVariable("id") Long id);//如果调用自己其他服务的api直接将其方法复制过来即可,下面这个就是从product当中复制过来的//    @GetMapping("/product/{id}")//    Product getProduct(@PathVariable("id") Long id);
}

5 展示借助81端口进行转发控制


6 断言规则

三 过滤器

1 将前置的请求参数给过滤掉,降低繁琐程度。

举例说明:路径重写(此时就可以将原先的@RequestMapping当中的参数给去除掉)

spring:cloud:gateway:routes:- id: order-routeuri: lb://service-orderpredicates:- Path=/api/order/**order: 0filters:- RewritePath=/api/order/(?<segment>.*), /$\{segment}- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**order: 1filters:- RewritePath=/api/product/(?<segment>.*), /$\{segment}- id: last-routeuri: https://cn.bing.compredicates:- Path=/**order: 2

实现目的,就是说如果请求的前缀固定含有某些内容,我们就可以借助这个过滤器将这些请求前缀给过滤掉,比如说访问路径http://localhost:81/api/product/product/1

但是后端接收就可以按照 http://localhost:81/product/1来进行接收,(暂时感觉)也就简化了一个@RequestMapping的注解

2 默认过滤器

使用 default-filters 可以全局加响应头

spring:cloud:gateway:routes:- id: order-routeuri: lb://service-orderpredicates:- Path=/api/order/**order: 0filters:- RewritePath=/api/order/(?<segment>.*), /$\{segment}- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**order: 1filters:- RewritePath=/api/product/(?<segment>.*), /$\{segment}- id: last-routeuri: https://cn.bing.compredicates:- Path=/**order: 2default-filters:- AddResponseHeader=X-Response-Abc, 123

携带了一个响应头参数

3 全局过滤器

代码展示:

package com.ax.gateway.filter;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.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Slf4j
@Component
public class RtGlobalFilter implements GlobalFilter, Ordered {/*** 全局过滤器** @param exchange* @param chain* @return*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String path = request.getPath().toString();long startTime = System.currentTimeMillis(); // 记录开始时间log.info("请求开始: path={}, startTime={}", path, startTime);return chain.filter(exchange).doFinally(signalType -> {long endTime = System.currentTimeMillis(); // 记录结束时间long duration = endTime - startTime;      // 计算耗时log.info("请求结束: path={}, endTime={}, 耗时: {}ms", path, endTime, duration);});}/*** 优先级** @return*/@Overridepublic int getOrder() {return 0;}
}

示例:

4 自定义过滤器工厂

自定义过滤器工厂(拦截器的名称也有特殊要求)Spring Cloud Gateway 要求自定义过滤器工厂的类名必须以 GatewayFilterFactory 结尾。

package com.ax.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.UUID;@Component
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//每次响应之前添加一个一次性令牌return chain.filter(exchange).then(Mono.fromRunnable(() -> {ServerHttpResponse response = exchange.getResponse();HttpHeaders headers = response.getHeaders();String value = config.getValue();if ("uuid".equalsIgnoreCase(value)) {value = UUID.randomUUID().toString();}if ("jwt".equalsIgnoreCase(value)) {value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY" +"3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NTY1NDA" +"xMTksImFkbWluIjp0cnVlLCJyb2xlcyI6WyJ1c2VyIiwiYWRtaW4iX" +"SwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSJ9.SflKxwRJSMeKKF" +"2QT4fwpMeJf36POk6yJV_adQssw5c";}headers.add(config.getName(), value);}));}};}
}

配置文件(OnceToken....)

spring:cloud:gateway:routes:- id: order-routeuri: lb://service-orderpredicates:- Path=/api/order/**order: 0filters:- RewritePath=/api/order/(?<segment>.*), /$\{segment}- OnceToken=X-Response-Token,uuid- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**order: 1filters:- RewritePath=/api/product/(?<segment>.*), /$\{segment}- id: last-routeuri: https://cn.bing.compredicates:- Path=/**order: 2default-filters:- AddResponseHeader=X-Response-Abc, 123

结果展示

5 全局跨域问题

全局跨域(CORS)问题 主要是与前端请求不同源的后端接口时,如何解决跨域问题(Cross-Origin Resource Sharing, CORS)。Spring Cloud Gateway 作为网关,它通常会充当微服务之间的流量调度中心,并需要解决跨域请求的问题,确保前端可以安全地与后端进行交互。

代码实现:

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowed-origin-patterns: '*'allowed-headers: '*'allowed-methods: '*'routes:- id: order-routeuri: lb://service-orderpredicates:- Path=/api/order/**order: 0filters:- RewritePath=/api/order/(?<segment>.*), /$\{segment}- OnceToken=X-Response-Token,uuid- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**order: 1filters:- RewritePath=/api/product/(?<segment>.*), /$\{segment}- id: last-routeuri: https://cn.bing.compredicates:- Path=/**order: 2default-filters:- AddResponseHeader=X-Response-Abc, 123

结果展示:

http://www.xdnf.cn/news/19180.html

相关文章:

  • java字节码增强,安全问题?
  • MySQL-事务(上)
  • 【分享】如何显示Chatgpt聊天的时间
  • 用Git在 Ubuntu 22.04(Git 2.34.1)把 ROS 2 工作空间上传到全新的 GitHub 仓库 步骤
  • 系统质量属性
  • Git 安装与国内加速(配置 SSH Key + 镜像克隆)
  • 设置word引用zotero中的参考文献的格式为中文引用格式或中英文格式
  • 电子战:Maritime SIGINT Architecture Technical Standards Handbook
  • Linux之Shell编程(三)流程控制
  • 深度学习重塑医疗:四大创新应用开启健康新纪元
  • 深度学习系列 | Seq2Seq端到端翻译模型
  • Ansible Playbook 调试与预演指南:从语法检查到连通性排查
  • Qt QML注册全局对象并调用其函数和属性
  • 针对 “TCP 连接中断 / 终止阶段” 的攻击
  • PostgreSQL 灾备核心详解:基于日志文件传输的物理复制(流复制)
  • LINUX-网络编程-TCP-UDP
  • 【光照】[光照模型]发展里程碑时间线
  • 拆解《AUTOSAR Adaptive Platform Core》(Core.pdf)—— 汽车电子的 “基础技术说明书”
  • 无网络安装来自 GitHub 的 Python 包
  • More Effective C++ 条款18:分期摊还预期的计算成本(Amortize the Cost of Expected Computations)
  • 构建坚不可摧的数据堡垒:深入解析 Oracle 高可用与容灾技术体系
  • 开发中使用——鸿蒙CoreSpeechKit让文字发声
  • 基于SpringBoot的电脑商城系统【2026最新】
  • 【C++】第二十七节—C++11(下) | 可变参数模版+新的类功能+STL中一些变化+包装器
  • Gray Code (格雷码)
  • 【机器学习入门】4.1 聚类简介——从“物以类聚”看懂无监督分组的核心逻辑
  • 【蓝桥杯 2024 省 Python B】缴纳过路费
  • 网格纹理采样算法
  • SEO关键词布局总踩坑?用腾讯云AI工具从核心词到长尾词一键生成(附青少年英语培训实操案例)
  • 文件,目录,字符串使用