Spring-Cloud-Gateway Predicate谓词(断言)使用与自定义

自定义路由谓词需要继承 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

 

原文地址:https://www.cnblogs.com/linjiqin/p/13643002.html