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

1.Predicate的使用

1.1是什么

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

1.2Route Predicate Factories这个是什么

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

1.3常用的Route Predicate

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

1.3.1After Route Predicate

根据配置时间来匹配路由

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

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

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

 Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
1.3.3.Between Route Predicate

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

- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] ,  2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
1.3.4.Cookie Route Predicate

在这里插入图片描述

 - Cookie==chocolate,mic    

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

1.3.5. Header Route Predicate

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

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

响应404:

{
  "timestamp": "2020-09-03T01:43:53.306+0000",
  "path": "/payment/get/2",
  "status": 404,
  "error": "Not Found",
  "message": null,
  "requestId": "692024c2"
}

加上Header请求:

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

响应:

{
  "code": 200,
  "message": "查询成功,serverPort:  8086",
  "data": {
    "id": 2,
    "serial": "22222"
  }
}
1.3.6.Host Route Predicate

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

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

响应404:

{
  "timestamp": "2020-09-03T03:19:30.783+0000",
  "path": "/payment/get/2",
  "status": 404,
  "error": "Not Found",
  "message": null,
  "requestId": "29a76d7b"
}

加上Host请求

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

响应:

{
  "code": 200,
  "message": "查询成功,serverPort:  8086",
  "data": {
    "id": 2,
    "serial": "22222"
  }
}

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

1.3.7 Method Route Predicate

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

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

1.3.8.Path Route Predicate

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

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - 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

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar

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

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

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/foo/{segment}
        filters:
        - AddRequestHeader=X-Request-Foo, Bar-{segment}

AddRequestParameter GatewayFilter Factory

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=foo, bar

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

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

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

    }

测试:

### 查询
GET http://localhost:8084/v2/payment/test
Accept: application/json

结果:

{
  "code": 200,
  "message": "查询成功,serverPort:  8086",
  "data": "1234:sasaas"
}

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()方法进行设置。

import com.alibaba.fastjson.JSONObject;
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.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Created by niugang on 2020-09-04 10:15
 */
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("*********come in MyLogGateWayFilter: " + LocalDateTime.now());
        HttpHeaders headers = exchange.getRequest().getHeaders();
        log.info("All headers:{}", headers);
        List<String> ticket = headers.get("ticket");
        if (ticket == null || ticket.isEmpty()) {
            log.info("*****用户名为Null 非法用户,(┬_┬)");
            //给人家一个回应
            ServerHttpResponse originalResponse = exchange.getResponse();
            originalResponse.getHeaders().set("Content-Type","application/json;charset=UTF-8");
            originalResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("timestamp",System.currentTimeMillis());
            jsonObject.put("status",HttpStatus.UNAUTHORIZED.value());
            jsonObject.put("reason","未授权,请先登陆");

            DataBuffer buffer = originalResponse.bufferFactory().wrap(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
            return exchange.getResponse().writeWith(Flux.just(buffer));
        }
        return chain.filter(exchange);
    }



    @Override
    public int getOrder() {
        return 0;
    }
}

访问:

### 查询
GET http://localhost:8084/v2/payment/test
Accept: application/json

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

### 查询
GET http://localhost:8084/v2/payment/test
Accept: application/json
ticket: 1234445

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值