启动网关服务,查看控制台
根据配置时间来匹配路由
以下配置为,请求时间在指定时间点之后可以用 上面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]以下配置为,请求时间在指定时间点之前可用
Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]以下配置为,请求时间在指定时间之间可用
- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]以上配置的意思是,当前请求需要携带一个name=chocolate,并且value需要正则表达式匹配mic,才能路由到指定的uri上。
无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" } }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
根据HTTP请求的Method属性来匹配以实现路由
以上配置表示,如果HTTP请求的方法是GET或POST,都会路由到指定的uri上。
请求路径匹配路由时比较常见的路由匹配规则
spring: cloud: gateway: routes: - id: host_route uri: https://example.org predicates: - Path=/foo/{segment},/bar/{segment}如果请求路径为例如/foo/1或/foo/bar或/bar/baz,则此路由将匹配。
${segment}是比较特殊的占位符,/*表示单层路径匹配,/***表示多层路径匹配。
Query=username, \d+ #要有参数名称并且是正整数才能路由
说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理
只有两种
pre:在业务逻辑之前
post:在业务逻辑之后
只有两种
单一: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标头添加到所有匹配请求的下游响应标头中。
impiemerts GlobalFilter ,Ordered
当请求进入(并与路由匹配时,过滤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