代码演示
新建模块: cloud-gateway9527
pom.xml
添加gateway的dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
完整pom如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud201230</artifactId>
<groupId>com.banana</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-gateway9527</artifactId>
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--gateway也是一个微服务,也需要注册进Eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--引入自定义的api通用包-->
<dependency>
<groupId>com.banana</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--web Gateway不需要web依赖,会报错-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
</dependencies>
</project>
application.yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启注册中心路由功能,利用微服务名进行路由
# lower-case-service-id: true #匹配路径转小写
routes:
- id: payment_routh #路由ID,唯一,建议配合服务名
# 匹配规则: http://localhost:9527/payment/get/** 的所有uri都会跳转至 lb://cloud-payment-service/
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/**
- id: payment_routh2
#uri: http://localhost:8001
uri: lb://cloud-payment-service
predicates:
- Path=/payment/LoadBalancer/**
- After=2021-01-20T09:51:48.195+08:00[Asia/Shanghai] #after route 该匹配规则自上海时间2021-01-20早上9:51:48秒后生效
eureka:
instance:
hostname: cloud-gateway-service
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://localhost:7001/eureka
GateWayConfig.java
package com.banana.springcloud.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 以编码的方式实现路由
* 官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories
* @author layman
* @date 2021/1/19
*/
@Configuration
public class GateWayConfig {
/**
* 配置一个ID为 first 的路由规则
* 当访问地址:http://localhost:9527/guonei 时会自动转发到地址 http://news.baidu.com/guonei
* @param routeLocatorBuilder
* @return RouteLocator
*/
@Bean
public RouteLocator CustomerRouteLocatorFirst(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("first",r->r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
/**
* 配置一个ID为 second 的路由规则
* 当访问地址:http://localhost:9527/guoji 时会自动转发到地址 http://news.baidu.com/guoji
* uri配置http://news.baidu.com/和http://news.baidu.com/guoji的效果是一样的?
* 似乎会把path的值加到rui后面,如果没有就追加,如果有就不追加,所以path的值如果乱写就会匹配不上?
*/
@Bean
public RouteLocator CustomerRouteLocatorSecond(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("second",r->r.path("/text0215").uri("http://news.baidu.com/")).build();
return routes.build();
}
}
MyGlobalFilter.java
package com.banana.springcloud.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.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* @author layman
* @date 2021/1/20
*/
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
/**
* ServerWebExchange:服务网络交换器 ,存放着重要的请求-响应属性、请求实例和响应实例等等,有点像 Context上下文。
* 通过给定的GatewayFilterChain处理Web请求并且(可选)委托给下一个{WebFilter}
* @param exchange 当前服务器交换
* @param chain 提供了一种委托给下一个过滤器的方法
* @return {@code Mono<Void>} 指示请求处理何时完成
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("------------come in MyGlobalFilter----------------时间:"+ LocalDateTime.now());
//获取请求参数中的第一个参数
String username = exchange.getRequest().getQueryParams().getFirst("username");
if(username == null ){
log.info("------用户名为空,非法访问------");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
//放行,进入下个过滤器
return chain.filter(exchange);
}
/**
* 获取此对象的顺序值。
* <p>值越高,优先级越低。值越低,优先级越高。
* (在某种程度上),类似于Servlet {load on startup}值。
* <p>相同的顺序值,优先级会变得随意
* @return 顺序值
* @see java.lang.Integer#MIN_VALUE = -2147483648 最大优先级
* @see java.lang.Integer#MAX_VALUE = -2147483648 最小优先级
*/
@Override
public int getOrder() {
return 0;
}
}
TimeUtil
package com.banana.springcloud.util;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
/**
* 获取After断言中的时间格式
* @author layman
* @date 2021/1/20
*/
public class TimeUtil {
public static void main(String[] args) {
ZonedDateTime now = ZonedDateTime.now();
// 2021-01-20T09:51:48.195+08:00[Asia/Shanghai]
System.out.println(now);
System.out.println(LocalDateTime.now());
}
}
根据application.yml中的配置,
当访问 http://localhost:9527/payment/get/88 时,该uri都跳转至 lb://cloud-payment-service/payment/get/88
测试页面如下:
- tips:网关配置需要移除 spring-boot-starter-web 和 spring-boot-starter-actuator 两个dependency, 否则会报错!
推荐博客:
https://blog.csdn.net/qq_41402200/article/details/94333830
https://www.cnblogs.com/crazymakercircle/p/11704077.html