自定義路由謂詞需要繼承 AbstractRoutePredicateFactory 工廠類,重寫 apply() 方法的邏輯和shortcutFieldOrder方法。
在 apply() 方法中可以通過 serverWebExchange.getRequest() 拿到 ServerHttpRequest 對象,從而可以獲取到請求的參數、請求方式、請求頭等信息。
apply() 方法的參數是自定義的配置類,在使用的時候配置參數,在 apply 方法中直接獲取使用。
命名需要以 RoutePredicateFactory 結尾,比如 UserNameCheckRoutePredicateFactory,那么在使用的時候 UserNameCheck 就是這個路由謂詞工廠的名稱。代碼如下所示。
自定義路由謂詞可以根據業務重寫路徑匹配規則或請求路徑日志跟蹤。
本類例子:檢查請求參數中的userName是否與配置的數據相同,如果相同則允許訪問,否則不允許訪問
package com.lynch.gateway.predicate; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import org.springframework.web.server.ServerWebExchange; import javax.validation.constraints.NotEmpty; import java.util.function.Predicate; /** * 自定義謂詞工廠類 * * 1、繼承AbstractRoutePredicateFactory類 * 2、重寫apply方法 * 3、apply方法的參數是自定義的配置類,可以在apply方法中直接獲取使用配置參數。 * 4、類的命名需要以RoutePredicateFactory結尾 * * 本類例子:檢查請求參數中的userName是否與配置的數據相同,如果相同則允許訪問,否則不允許訪問 */ @Component public class UserNameCheckRoutePredicateFactory extends AbstractRoutePredicateFactory<UserNameCheckRoutePredicateFactory.Config> { public UserNameCheckRoutePredicateFactory() { super(Config.class); } @Override public Predicate<ServerWebExchange> apply(UserNameCheckRoutePredicateFactory.Config config) { // 寫法1
return new Predicate<ServerWebExchange>() { @Override public boolean test(ServerWebExchange serverWebExchange) { String userName = serverWebExchange.getRequest().getQueryParams().getFirst("userName"); if(StringUtils.isBlank(userName)){ return false; } //檢查請求參數中的userName是否與配置的數據相同,如果相同則允許訪問,否則不允許訪問
if(userName.equals(config.getName())){ return true; } return false; } }; // 寫法2
/* return serverWebExchange -> { String userName = serverWebExchange.getRequest().getQueryParams().getFirst("userName"); if(StringUtils.isBlank(userName)){ return false; } //檢查請求參數中的userName是否與配置的數據相同,如果相同則允許訪問,否則不允許訪問 if(userName.equals(config.getName())){ return true; } return false; }; */ } @Validated public static class Config{ @NotEmpty private String name; public String getName(){ return name; } public void setName(String name){ this.name=name; } } }
在application.yml中添加路由配置,如下:
spring: application: name: mima-cloud-gateway cloud: gateway: routes: #自定義謂詞UserNameCheckRoutePredicateFactory的配置使用 #謂詞用來匹配路徑 - id: Auth_route uri: lb://mima-cloud-producer
order: 1 predicates: - Path=/** # name配置為UserNameCheckRoutePredicateFactory類前綴UserNameCheck # 只有訪問http://localhost:8801/getheader?userName=lynch 才可以訪問,否則為404 # 必須攜帶userName請求參數,並且值為lynch - name: UserNameCheck args: name: lynch server: port: 8801 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true instance-id: ${spring.application.name}:${server.port} debug: true management: endpoints: web: exposure: include: '*' endpoint: health: show-details: always shutdown: true