路由過濾器 GatewayFilter


GatewayFilter是網關中提供的一種過濾器,可以對進入網關的請求微服務返回的響應做處理

Spring提供了31種不同的路由過濾器工廠

名稱

說明

AddRequestHeader

給當前請求添加一個請求頭

RemoveRequestHeader

移除請求中的一個請求頭

AddResponseHeader

給響應結果中添加一個響應頭

RemoveResponseHeader

從響應結果中移除有一個響應頭

RequestRateLimiter

限制請求的流量

...

 

路由過濾器

給所有進入userservice的請求添加一個請求頭:- AddRequestHeader=info, AddRequestHeader!

實現方式:在gateway項目中修改application.yml文件,給userservice的路由添加過濾器:

spring:
  cloud:
    gateway:
      routes: # 網關路由配置 - id: user-service
          uri: lb://userservice
          predicates:
            - Path=/user/**
          filters: # 過濾器
            - AddRequestHeader=info, AddRequestHeader! # 添加請求頭

userservice項目中controller中的請求方法上獲取Info的內容

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryByid(@PathVariable("id") Long id,
                          @RequestHeader(value = "Info",required = false) String info) {
        System.out.println(info);
        return userService.queryById(id);
    }
}

默認過濾器

如果要對所有的路由都生效,則可以將過濾器工廠寫到default下。格式如下

spring:
    gateway:
      routes: # 網關路由配置
        - id: user-service # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
          uri: lb://userservice # 路由的目標地址 lb就是負載均衡,后面跟服務名稱
          predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
            - Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
          #filters: # 過濾器
          #  - AddRequestHeader=info, AddRequestHeader! # 添加請求頭
        - id: feign-order-service
          uri: lb://feignorderservice
          predicates:
            - Path=/order/**
      default-filters: # 默認過濾器,會對所有的路由請求都生效 - AddRequestHeader=Info,'default filers request header!' # 添加請求頭

全局過濾器GlobalFilter

全局過濾器的作用也是處理一切進入網關的請求和微服務響應,和默認過濾器處理一樣,那為什么還要全局過濾器呢?

默認過濾器通過配置設定過濾器,過濾器的邏輯時固定的,無法根據項目需求隨意調整。

GlobalFilter的邏輯需要自己寫代碼實現

定義方式是實現GlobalFilter接口

public interface GlobalFilter {

    /**
     * Process the Web request and (optionally) delegate to the next {@code WebFilter}
     * through the given {@link GatewayFilterChain}.
     * @param exchange 請求上下文,可以獲取request、response等信息
     * @param chain 過濾器鏈,下一個過濾器
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

需求:定義全局過濾器,攔截請求,判斷請求的參數是否滿足下面條件:

  • 參數中是否有authorization,
  • authorization參數值是否為admin
  • 如果同時滿足則放行,否則攔截
//@Order(-1) //過濾器執行順序
@Component //spring容器管理
public class AuthorizationFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.獲取請求參數
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.獲取參數中的 authorization 參數
        String auth = params.getFirst("authorization");
        // 3.判斷參數值是否等於 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,攔截
        // 5.1.設置狀態碼
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.攔截請求
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

注意:Order注解和implements Ordered作用是完全一樣的,二選一即可

gateway項目結構

訪問:http://localhost:10018/user/1

訪問:http://localhost:10018/user/1?authorization=admin

過濾器執行順序

過濾器鏈那就會有過濾器執行順序

過濾器都必須指定一個int類型的order值,order值越小,優先級越高,執行順序越靠前。

GlobalFilter通過實現Ordered接口,或者添加@Order注解來指定order值

路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增

 

當過濾器的order值一樣時,會按照 defaultFilter 、 路由過濾器、 GlobalFilter的順序執行

 

 

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加載defaultFilters,然后再加載某個route的filters,然后合並
org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法會加載全局過濾器,與前面的過濾器合並后根據order排序,組織過濾器鏈

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM