預設 filter
預設的有 38 個,分為5組:請求頭、請求引數(查詢字串)、響應頭、字首和路徑、其他,作用都不是很大,挑幾個舉個例
# 請求和響應 filter
- id: test_my_consumer
uri: http://localhost:8082
predicates:
- Path=/feign/**
filters:
- AddRequestHeader=customer-header1,value1 # 請求頭自動新增 customer-header1,值為 value1
- AddRequestHeader=customer-header2,value2 # 請求頭自動新增 customer-header2,值為 value2
- RemoveRequestHeader=User-Agent # 移除請求頭引數 User-Agent
- SetRequestHeader=Content-Type,application/json;charset=UTF-8 # 修改請求頭引數
- AddRequestParameter=username,milk # url 查詢字串增加引數 username,值為 milk(如果請求url已經有username了,這裡就不再新增了)
- RemoveRequestParameter=userid # url 查詢字串增加引數移除 userid
- AddResponseHeader=customer-response-header1,response1
- RemoveResponseHeader=Content-Type
- SetResponseHeader=Date,2099-01-01
# 路徑字首 filter(最終還是一致的,頁面訪問 /user/1 實際訪問的是 /feign/user/1,作用是隱藏服務端真實地址)
- id: test_my_consumer2
uri: http://localhost:8083
predicates:
# - Path=/feign/user/** 真實地址 /feign/user/**
- Path=/user/** # 現在改為 /user/**
filters:
- PrefixPath=/fiegn # 加個字首,頁面訪問 /user/**,實際訪問的是 /feign/user/**
自定義過濾器
不說和 RoutePredicate 一摸一樣,至少可以說是大差不差
/**
* 類名也必須 GatewayFilterFactory 結尾,前面的就是自定義 filter 的名稱。這裡 My 就是 filter 的名稱
*/
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
public MyGatewayFilterFactory(){
super(Config.class);
}
@Override
public GatewayFilter apply(MyGatewayFilterFactory.Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
//如果 url 包含 username 引數就放行,不然就返回 404
if (request.getQueryParams().containsKey(config.getProperty())){
return chain.filter(exchange);
}else {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
};
}
// 啟用短促配置,自動對映配置檔案的值到 property
@Override
public List<String> shortcutFieldOrder() {
return List.of("property");
}
@Getter
@Setter
public static class Config
{
private String property; // 對應配置檔案 property 的引數的值
}
}
配置檔案,結合上面的自定義 filter 程式碼,全部的含義是:1,/feign/user/** 請求會應用 My 這個過濾器;2,配置檔案中的 username 將會對映到過濾器的 property 上;3,過濾器內部獲取 url 引數,如果有 username 引數就放行,不然就響應 404
- id: test_my_consumer
uri: http://localhost:8082
predicates:
- Path=/feign/user/**
filters:
- My=username # 短促配置,不用顯示指定 property 引數,自動把 username 對映到 property
自定義全域性過濾器
注意這是全域性過濾器,yaml 不需要配置
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpHeaders headers = exchange.getRequest().getHeaders();
if (headers.isEmpty()){
throw new RuntimeException("請求頭為空");
}
if (!headers.containsKey("access-token")){
throw new RuntimeException("請求頭沒有access-token");
}
String token = headers.getFirst("access-token");
if (StringUtils.hasText(token)){
throw new RuntimeException("請求頭access-token為空");
}
// 到 redis 驗證,token 是否合法
if (!exist(token)){
throw new RuntimeException("access-token不合法");
}
// 返回過濾器(請求都會應用這個過濾器)
return chain.filter(exchange);
}
/**
* 數字越小,優先順序越高
*/
@Override
public int getOrder() {
return 0;
}
}