SpringCloud Api Gateway+Consul 动态路由+过滤器Filter
1.工程pom.xml 引入 依赖
<!-- spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
注意web的依赖要移除掉,不然会报错。
2.添加启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@ComponentScan(basePackages= {"com.company.*"})
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
在启动类中增加 注解 @EnableDiscoveryClient
3.配置yml文件
1.配置ApiGateway进consul注册中心
spring:
application:
name: apigateway
consul:
host: localhost
port: 8500
2.配置ApiGateway进consul注册中心
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true
routes:
- id: service #路由的ID
#uri: http://localhost:8082
uri: lb://application #匹配后提共服务的路由地址
predicates:
- Path=/service/**
filters:
- StripPrefix=1
# 熔断降级配置
- name: Hystrix
args:
name: default
fallbackUri: forward:/fallback
4.分别启动consul、service、apigateway
1.每个服务都启动好
2.输入地址查看运行结果:http://localhost:8500/ui/dc1/services
一定要将服务与网关注册到consul里面去
5.测试
1.访问gateway地址
访问成功
6.过滤器Filter
1.创建AuthorizeFilter类
package com.company.author;
import cn.hutool.core.collection.CollUtil;
import com.company.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
/**
* 过滤器
*/
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {
//放行的路径
private static List<String> whiteList = new ArrayList<>();
static {
whiteList.add("/service/login/login");
whiteList.add("/service/school/getSchoolList");
whiteList.add("/service/school/getSchoolSectionSubjectList");
whiteList.add("/service/register/checkPhone");
whiteList.add("/service/register/getVerifyCode");
whiteList.add("/service/register/register");
whiteList.add("/service/swagger-resources/**");
whiteList.add("/service/webjars/**");
whiteList.add("/service/v2/**");
whiteList.add("/service/doc.html/**");
whiteList.add("/service/knowledge/getAllCfgSection");
}
//过滤
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("***************come in AuthorizeFilter*************************");
ServerHttpRequest httpRequest = exchange.getRequest();
//获取url
String url = httpRequest.getURI().getPath();
//判断url是否直接放行
if (whiteList.contains(url)) {
return chain.filter(exchange);
}
//通过token判断用户是否登录
String token =null;
if(CollUtil.isNotEmpty(exchange.getRequest().getQueryParams())){
token = exchange.getRequest().getQueryParams().get("token").get(0);
}
String token1 = httpRequest.getHeaders().getFirst("token");
// 缓存存在
if (StringUtils.isEmpty(token) && StringUtils.isEmpty(token1)) {
ServerHttpResponse serverHttpResponse = exchange.getResponse();
String rsp = "{\"code\":\"2\",\"message\":\"用户未登陆\"}";
DataBuffer d = serverHttpResponse.bufferFactory().wrap(rsp.getBytes());
//指定编码
serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return serverHttpResponse.writeWith(Flux.just(d));
}
//校验token是否过期
Object userObj = RedisUtil.get(token);
Object userObj1 = RedisUtil.get(token1);
if (userObj == null && userObj1 == null) {
ServerHttpResponse serverHttpResponse = exchange.getResponse();
String rsp = "{\"code\":\"2\",\"message\":\"token已失效\"}";
DataBuffer d = serverHttpResponse.bufferFactory().wrap(rsp.getBytes());
//指定编码
serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return serverHttpResponse.writeWith(Flux.just(d));
}
return chain.filter(exchange);
}
//按级别进行
@Override
public int getOrder() {
return 0;
}
}