ToB企服应用市场:ToB评测及商务社交产业平台

标题: Spring Cloud Gateway编码实现任意地址跳转 [打印本页]

作者: 莫张周刘王    时间: 2023-6-27 09:13
标题: Spring Cloud Gateway编码实现任意地址跳转
欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览

一般路由规则

  1. spring:
  2.   application:
  3.     name: hello-gateway
  4.   cloud:
  5.     gateway:
  6.       routes:
  7.         - id: path_route
  8.           uri: http://127.0.0.1:8082
  9.           predicates:
  10.           - Path=/hello/**
复制代码
特殊规则

设计


源码下载

名称链接备注项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
编码

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <parent>
  6.         <artifactId>spring-cloud-tutorials</artifactId>
  7.         <groupId>com.bolingcavalry</groupId>
  8.         <version>1.0-SNAPSHOT</version>
  9.     </parent>
  10.     <modelVersion>4.0.0</modelVersion>
  11.     <artifactId>gateway-dynamic-route</artifactId>
  12.     <dependencies>
  13.         <dependency>
  14.             <groupId>com.bolingcavalry</groupId>
  15.             <artifactId>common</artifactId>
  16.             <version>${project.version}</version>
  17.         </dependency>
  18.         <dependency>
  19.             <groupId>org.springframework.cloud</groupId>
  20.             <artifactId>spring-cloud-starter-gateway</artifactId>
  21.         </dependency>
  22.     </dependencies>
  23.     <build>
  24.         <plugins>
  25.             
  26.             <plugin>
  27.                 <groupId>org.springframework.boot</groupId>
  28.                 <artifactId>spring-boot-maven-plugin</artifactId>
  29.                 <configuration>
  30.                     <mainClass>com.bolingcavalry.gateway.GatewayDynamicRouteApplication</mainClass>
  31.                 </configuration>
  32.                 <executions>
  33.                     <execution>
  34.                         <goals>
  35.                             <goal>repackage</goal>
  36.                         </goals>
  37.                     </execution>
  38.                 </executions>
  39.             </plugin>
  40.         </plugins>
  41.     </build>
  42. </project>
复制代码
  1. package com.bolingcavalry.gateway;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class GatewayDynamicRouteApplication {
  6.     public static void main(String[] args) {
  7.         SpringApplication.run(GatewayDynamicRouteApplication.class,args);
  8.     }
  9. }
复制代码
  1. package com.bolingcavalry.gateway.filter;
  2. import lombok.Data;
  3. import lombok.ToString;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.cloud.gateway.filter.GatewayFilter;
  6. import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
  7. import org.springframework.cloud.gateway.route.Route;
  8. import org.springframework.http.HttpHeaders;
  9. import org.springframework.http.HttpMethod;
  10. import org.springframework.http.server.reactive.ServerHttpRequest;
  11. import org.springframework.stereotype.Component;
  12. import org.springframework.util.MultiValueMap;
  13. import org.springframework.web.util.UriComponentsBuilder;
  14. import java.net.URI;
  15. import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
  16. @Component
  17. @Slf4j
  18. public class BizLogicRouteGatewayFilterFactory extends AbstractGatewayFilterFactory<BizLogicRouteGatewayFilterFactory.BizLogicRouteConfig> {
  19.     private static final String TAG_TEST_USER = "tag-test-user";
  20.     public BizLogicRouteGatewayFilterFactory() {
  21.         super(BizLogicRouteConfig.class);
  22.     }
  23.     @Override
  24.     public GatewayFilter apply(BizLogicRouteConfig config) {
  25.         return (exchange, chain) -> {
  26.             // 本次的请求对象
  27.             ServerHttpRequest request =  exchange.getRequest();
  28.             // 调用方请求时的path
  29.             String rawPath = request.getURI().getRawPath();
  30.             log.info("rawPath [{}]", rawPath);
  31.             // 请求头
  32.             HttpHeaders headers = request.getHeaders();
  33.             // 请求方法
  34.             HttpMethod httpMethod = request.getMethod();
  35.             // 请求参数
  36.             MultiValueMap<String, String> queryParams = request.getQueryParams();
  37.             // 这就是定制的业务逻辑,isTestUser等于ture代表当前请求来自测试用户,需要被转发到测试环境
  38.             boolean isTestUser = false;
  39.             // 如果header中有tag-test-user这个key,并且值等于true(不区分大小写),
  40.             // 就认为当前请求是测试用户发来的
  41.             if (headers.containsKey(TAG_TEST_USER)) {
  42.                 String tageTestUser = headers.get(TAG_TEST_USER).get(0);
  43.                 if ("true".equalsIgnoreCase(tageTestUser)) {
  44.                     isTestUser = true;
  45.                 }
  46.             }
  47.             URI uri;
  48.             if (isTestUser) {
  49.                 log.info("这是测试用户的请求");
  50.                 // 从配置文件中得到测试环境的uri
  51.                 uri = UriComponentsBuilder.fromHttpUrl(config.getTestEnvUri() + rawPath).queryParams(queryParams).build().toUri();
  52.             } else {
  53.                 log.info("这是普通用户的请求");
  54.                 // 从配置文件中得到正式环境的uri
  55.                 uri = UriComponentsBuilder.fromHttpUrl(config.getProdEnvUri() + rawPath).queryParams(queryParams).build().toUri();
  56.             }
  57.             // 生成新的Request对象,该对象放弃了常规路由配置中的spring.cloud.gateway.routes.uri字段
  58.             ServerHttpRequest serverHttpRequest = request.mutate().uri(uri).method(httpMethod).headers(httpHeaders -> httpHeaders = httpHeaders).build();
  59.             // 取出当前的route对象
  60.             Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
  61.             //从新设置Route地址
  62.             Route newRoute =
  63.                     Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId())
  64.                             .order(route.getOrder()).uri(uri).build();
  65.             // 放回exchange中
  66.             exchange.getAttributes().put(GATEWAY_ROUTE_ATTR,newRoute);
  67.             // 链式处理,交给下一个过滤器
  68.             return chain.filter(exchange.mutate().request(serverHttpRequest).build());
  69.         };
  70.     }
  71.     /**
  72.      * 这是过滤器的配置类,配置信息会保存在此处
  73.      */
  74.     @Data
  75.     @ToString
  76.     public static class BizLogicRouteConfig {
  77.         // 生产环境的服务地址
  78.         private String prodEnvUri;
  79.         // 测试环境的服务地址
  80.         private String testEnvUri;
  81.     }
  82. }
复制代码
配置

  1. server:
  2.   #服务端口
  3.   port: 8086
  4. spring:
  5.   application:
  6.     name: gateway-dynamic-route
  7.   cloud:
  8.     gateway:
  9.       routes:
  10.         - id: path_route
  11.           uri: http://0.0.0.0:8082
  12.           predicates:
  13.           - Path=/hello/**
  14.           filters:
  15.             - name: BizLogicRoute
  16.               args:
  17.                 prodEnvUri: http://127.0.0.1:8082
  18.                 testEnvUri: http://127.0.0.1:8087
复制代码
开发和启动后台服务,模拟生产和测试环境

  1. package com.bolingcavalry.provider.controller;
  2. import com.bolingcavalry.common.Constants;
  3. import org.springframework.web.bind.annotation.*;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.Map;
  7. @RestController
  8. @RequestMapping("/hello")
  9. public class Hello {
  10.     private String dateStr(){
  11.         return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
  12.     }
  13.     /**
  14.      * 返回字符串类型
  15.      * @return
  16.      */
  17.     @GetMapping("/str")
  18.     public String helloStr() {
  19.         return Constants.HELLO_PREFIX + ", " + dateStr() + " (from test enviroment)";
  20.     }
  21. }
复制代码
验证

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4