Spring Cloud Gateway
基础使用
//依赖
spring-cloud-starter-gateway
//不能添加springweb依赖,网关采用netty,web采用tomcat- application.yml
//application.yml
server: 80
spring:
application:
#服务名称
name: gateway
cloud:
#配置网关
gateway:
discovery:
locator:
enable: true #启用DiscoveryClient网关集成,可以实现服务发现
#配置网关路由转发规则,是否转发以及转发路径
routes:
- id: route1
#负载均衡 + 服务名称
uri: lb://demo
#谓词:是否匹配,可用正则,共11种谓词,以下为Path
predicates:
- Path=/test, /index, /test*/**
#过滤器,提供31种,可对请求和响应进行操作
filters:
- AddRequestHeader=Context-Type, application-json
#服务注册发现
nacos:
discovery:
server-addr: 192.168.2.8:8848
password: nacos
username: nacos
#哨兵
sentinel:
eager: true
transport:
dashboard: 192.168.2.8:8849集成Swagger3.0.0
pom.xml 添加
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
</dependency>添加 SwaggerProvider
/**
* 聚合系统接口
* @author Skwax
*/
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider
{
/**
* swagger3默认的url后缀
*/
private static final String SWAGGER3URL = "/v3/api-docs";
/**
* 网关路由
*/
private final RouteLocator routeLocator;
/**
* gateway配置文件
*/
private final GatewayProperties gatewayProperties;
/**
* 网关应用名称
*/
@Value("${spring.application.name}")
private String self;
@Autowired
public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}
/**
* 对于gateway来说这块比较重要 让swagger能找到对应的服务
*
* @return
*/
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
//从配置文件中获取并配置SwaggerResource
gatewayProperties.getRoutes().stream()
//过滤路由
.filter(routeDefinition -> routes.contains(routeDefinition.getId()))
//循环添加,从路由的断言中获取,一般来说路由都会配置断言Path信息,这就不多说了
.forEach(route -> {
route.getPredicates().stream()
//获取Path信息
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
//开始添加SwaggerResource
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", SWAGGER3URL))));
});
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(DocumentationType.OAS_30.getVersion());
return swaggerResource;
}
}集成Sentinel
pom.xml 添加
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel Datasource Nacos -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>自定义谓词
predicates:
- Token=12345- 定义配置类,用于承载配置参数
import lombok.Data;
@Data
public class TokenConfig {
private String Token;
}- 定义路由谓词工厂,类名固定格式
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.web.server.ServerWebExchange;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenConfig> {
public TokenRoutePredicateFactory()
{
super(TokenConfig.class);
}
/*
将yml配置中的Token值存入TokenConfig类
*/
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("token");
}
/*
具体判断逻辑,返回true/false
*/
@Override
public Predicate<ServerWebExchange> apply(TokenConfig config) {
return exchange -> {
//获取yml中配置的Token
var token = config.getToken();
//获取请求的request
var request = exchange.getRequest();
return true;
};
}
}自定义过滤器
filters: - RequestLog=user, dsqda- 自定义网关过滤工厂
import org.springframework.cloud.gateway.filter.GatewayFilter;import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;import org.springframework.stereotype.Component;@Componentpublic class RequestLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { @Override public GatewayFilter apply(NameValueConfig config) { return (exchange,chain)->{ //yml中filter配置的名称和值 config.getName(); config.getValue(); //请求 var request = exchange.getRequest(); return chain.filter(exchange); }; }}自定义全局过滤器
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class CustomeGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange);
}
//数值越小越靠前
@Override
public int getOrder() {
return 0;
}
}跨域
- 增加配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter(){
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
}
评论