Spring Cloud Gateway新一代网关(下篇)

忘是亡心i 2022-12-03 15:53 302阅读 0赞

1.Predicate的使用

1.1是什么

启动网关服务,查看控制台
在这里插入图片描述

1.2Route Predicate Factories这个是什么

在这里插入图片描述
在这里插入图片描述

1.3常用的Route Predicate

在这里插入图片描述
在这里插入图片描述

1.3.1After Route Predicate

根据配置时间来匹配路由

以下配置为,请求时间在指定时间点之后可以用
在这里插入图片描述
上面yaml中配置的时间戳,是默认时区时间戳。

  1. public static void main(String[] args) {
  2. ZonedDateTime now = ZonedDateTime.now();
  3. System.out.println(now);//2020-09-02T19:46:53.590+08:00[Asia/Shanghai]
  4. }
  5. - After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

1.3.2Before Route Predicate

以下配置为,请求时间在指定时间点之前可用

  1. Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

1.3.3.Between Route Predicate

以下配置为,请求时间在指定时间之间可用

  1. - Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

在这里插入图片描述

  1. - Cookie==chocolate,mic

以上配置的意思是,当前请求需要携带一个name=chocolate,并且value需要正则表达式匹配mic,才能路由到指定的uri上。

1.3.5. Header Route Predicate

在这里插入图片描述
在这里插入图片描述
无Header请求:

  1. ### 查询
  2. GET http://localhost:8084/payment/get/2
  3. Accept: application/json

响应404:

  1. {
  2. "timestamp": "2020-09-03T01:43:53.306+0000",
  3. "path": "/payment/get/2",
  4. "status": 404,
  5. "error": "Not Found",
  6. "message": null,
  7. "requestId": "692024c2"
  8. }

加上Header请求:

  1. ### 查询
  2. GET http://localhost:8084/payment/get/2
  3. Accept: application/json
  4. X-Request-ID: 112334

响应:

  1. {
  2. "code": 200,
  3. "message": "查询成功,serverPort: 8086",
  4. "data": {
  5. "id": 2,
  6. "serial": "22222"
  7. }
  8. }

1.3.6.Host Route Predicate

HTTP请求会携带一个Host字段,这个字段表示请求的服务器网址
在这里插入图片描述
无Host请求:

  1. ### 查询
  2. GET http://localhost:8084/payment/get/2
  3. Accept: application/json

响应404:

  1. {
  2. "timestamp": "2020-09-03T03:19:30.783+0000",
  3. "path": "/payment/get/2",
  4. "status": 404,
  5. "error": "Not Found",
  6. "message": null,
  7. "requestId": "29a76d7b"
  8. }

加上Host请求

  1. ### 查询
  2. GET http://localhost:8084/payment/get/2
  3. Accept: application/json
  4. Host: 11.aa.com

响应:

  1. {
  2. "code": 200,
  3. "message": "查询成功,serverPort: 8086",
  4. "data": {
  5. "id": 2,
  6. "serial": "22222"
  7. }
  8. }

加上错误的Host,响应也是404

1.3.7 Method Route Predicate

根据HTTP请求的Method属性来匹配以实现路由
在这里插入图片描述

以上配置表示,如果HTTP请求的方法是GET或POST,都会路由到指定的uri上。

1.3.8.Path Route Predicate

请求路径匹配路由时比较常见的路由匹配规则

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: host_route
  6. uri: https://example.org
  7. predicates:
  8. - Path=/foo/{ segment},/bar/{ segment}

如果请求路径为例如/foo/1或/foo/bar或/bar/baz,则此路由将匹配。

${segment}是比较特殊的占位符,/*表示单层路径匹配,/***表示多层路径匹配。

1.3.99. Query Route Predicate

Query=username, \d+ #要有参数名称并且是正整数才能路由

1.4小总结

说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理

2.Filter的使用

2.1是什么

在这里插入图片描述

2.2Spring Cloud Gateway的Filter

2.2.1生命周期

只有两种

pre:在业务逻辑之前

post:在业务逻辑之后

2.2.2种类

只有两种

单一:GatewayFilter
在这里插入图片描述

全局:GlobalFilter

路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。 路由过滤器适用于特定路由。 Spring Cloud Gateway包括许多内置的GatewayFilter工厂。
在这里插入图片描述
AddRequestHeader GatewayFilter Factory

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_header_route
  6. uri: https://example.org
  7. filters:
  8. - AddRequestHeader=X-Request-Foo, Bar

这会将X-Request-Foo:Bar标头添加到所有匹配请求的下游请求标头中。

AddRequestHeader知道用于匹配路径或主机的URI变量。 URI变量可用于该值,并将在运行时扩展。

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_header_route
  6. uri: https://example.org
  7. predicates:
  8. - Path=/foo/{ segment}
  9. filters:
  10. - AddRequestHeader=X-Request-Foo, Bar-{ segment}

AddRequestParameter GatewayFilter Factory

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_parameter_route
  6. uri: https://example.org
  7. filters:
  8. - AddRequestParameter=foo, bar

这会将foo = bar添加到所有匹配请求的下游请求的查询字符串中。

配置
在这里插入图片描述
下游controller

  1. @RequestMapping(value = "/v2/payment/test")
  2. public CommonResult<Payment> getPaymentTestById(@RequestHeader("XRequestID") Integer XRequestID,String queryParams) {
  3. return new CommonResult(200, "查询成功,serverPort: " + serverPort, XRequestID+":"+queryParams);
  4. }

测试:

  1. ### 查询
  2. GET http://localhost:8084/v2/payment/test
  3. Accept: application/json

结果:

  1. {
  2. "code": 200,
  3. "message": "查询成功,serverPort: 8086",
  4. "data": "1234:sasaas"
  5. }

AddResponseHeader GatewayFilter Factory
在这里插入图片描述
这会将X-Response-Foo:Bar标头添加到所有匹配请求的下游响应标头中。

在这里插入图片描述

2.3自定义过滤器,自定义全局GlobalFilter

2.3.1两个主要接口介绍

impiemerts GlobalFilter ,Ordered

2.3.2能干什么

  • 全局日志记录
  • 统一网关鉴权
  • 等等

2.3.3代码案例

当请求进入(并与路由匹配时,过滤Web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有特定于路由的实例添加到过滤器链中。 该组合的过滤器链由org.springframework.core.Ordered接口排序,可以通过实现getOrder()方法进行设置。

  1. import com.alibaba.fastjson.JSONObject;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  4. import org.springframework.cloud.gateway.filter.GlobalFilter;
  5. import org.springframework.core.Ordered;
  6. import org.springframework.core.io.buffer.DataBuffer;
  7. import org.springframework.http.HttpHeaders;
  8. import org.springframework.http.HttpStatus;
  9. import org.springframework.http.server.reactive.ServerHttpResponse;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.server.ServerWebExchange;
  12. import reactor.core.publisher.Flux;
  13. import reactor.core.publisher.Mono;
  14. import java.nio.charset.StandardCharsets;
  15. import java.time.LocalDateTime;
  16. import java.util.List;
  17. /** * @author Created by niugang on 2020-09-04 10:15 */
  18. @Component
  19. @Slf4j
  20. public class MyLogGateWayFilter implements GlobalFilter, Ordered {
  21. @Override
  22. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  23. log.info("*********come in MyLogGateWayFilter: " + LocalDateTime.now());
  24. HttpHeaders headers = exchange.getRequest().getHeaders();
  25. log.info("All headers:{}", headers);
  26. List<String> ticket = headers.get("ticket");
  27. if (ticket == null || ticket.isEmpty()) {
  28. log.info("*****用户名为Null 非法用户,(┬_┬)");
  29. //给人家一个回应
  30. ServerHttpResponse originalResponse = exchange.getResponse();
  31. originalResponse.getHeaders().set("Content-Type","application/json;charset=UTF-8");
  32. originalResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
  33. JSONObject jsonObject = new JSONObject();
  34. jsonObject.put("timestamp",System.currentTimeMillis());
  35. jsonObject.put("status",HttpStatus.UNAUTHORIZED.value());
  36. jsonObject.put("reason","未授权,请先登陆");
  37. DataBuffer buffer = originalResponse.bufferFactory().wrap(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
  38. return exchange.getResponse().writeWith(Flux.just(buffer));
  39. }
  40. return chain.filter(exchange);
  41. }
  42. @Override
  43. public int getOrder() {
  44. return 0;
  45. }
  46. }

访问:

  1. ### 查询
  2. GET http://localhost:8084/v2/payment/test
  3. Accept: application/json

响应:
在这里插入图片描述
增加ticket:

  1. ### 查询
  2. GET http://localhost:8084/v2/payment/test
  3. Accept: application/json
  4. ticket: 1234445

在这里插入图片描述
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,302人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring Cloud:Gateway

    不同的微服务一般来说会有不同的网络地址,客户端在访问的时候,如果需要记住这些地址的话,其实是很复杂的,而且也很难进行维护客户端会请求多个不同的服务,需要维护不同的请求地址...