场景:
使用网关路由的情况,当匹配某个路径时自动转发到其他的服务,没匹配不转发
如: 访问localhost/test/时 转发到 localhost:1111/
访问localhost/aa/** 时 不转发
正题
1、先搭gateway架子
把下面这引入,这样已经可以用了
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8"
}
}
2、上配置
application.yml
server:
port: 80
spring:
cloud:
gateway:
routes:
- id: neo_route #id 随便起个不重复的名字
uri: http://localhost:8011 #路由目的服务的基础访问路径
predicates:
- Path=test/data/** #匹配规则,可模糊匹配,匹配到这个路径就路由转发
filters:
- StripPrefix=2 #截取前两个路径
- name: Authorize # 自定义过滤器
- name: Hystrix # 路由后服务未启动时熔断
args:
name: fallCallback
fallbackUri: forward:/fall #自己给的默认实现
3、 编写过滤器
3.1 定义过滤过程想干的事
坑:AuthorizeGatewayFilter这个名称要注意了,** **GatewayFilter这样的格式。然后****部分就是过滤器的名字
**GatewayFilter
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class AuthorizeGatewayFilter implements GatewayFilter, Ordered {
Logger logger = LoggerFactory.getLogger(AuthorizeGatewayFilter.class);
private static String HEADER_KEY = "token";
@Override
public int getOrder() {
return 100;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String headerToken = request.getHeaders().getFirst(HEADER_KEY);
if(StringUtils.isEmpty(headerToken)) {
return buildCallback(exchange,HttpStatus.PROXY_AUTHENTICATION_REQUIRED, CallbackResponse.NO_HEADER_TOKEN);
}
return chain.filter(exchange);
}
private Mono<Void> buildCallback(ServerWebExchange exchange, HttpStatus status, Object msg) {
return Mono.defer(()->{
exchange.getResponse().setStatusCode(status);
CallbackInfo callbackInfo = CallbackInfo.copyResponse(msg);
DataBuffer wrap = exchange.getResponse().bufferFactory().wrap("這就是返回值".getBytes());
return exchange.getResponse().writeWith(Flux.just(wrap));
});
}
}
3.2 spring管理起来
import cn.togeek.gateway.filter.AuthorizeGatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
@Override
public GatewayFilter apply(Object config) {
return new AuthorizeGatewayFilter();
}
}
4、定义路由失败后的回调
就是个controller
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping
public class FallCallbackController {
@GetMapping("/fall")
public ResponseEntity<?> fallCallback(){
return new ResponseEntity<>("api异常,请稍后重试", HttpStatus.BAD_GATEWAY);
}
}
5、使用
访问 localhost/test/data/aa 路由到了 localhost:8011/aa (在application.yml中路徑截取了两个)