• 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

     

  • 相关阅读:
    解决windows上安装TortoiseSVN后不能使用命令行问题
    Python里Pure paths、PurePosixPath、PureWindowsPath的区别
    PHP数组运算符
    global,local,static的区别
    echo和print的区别
    PHP中foreach循环传值问题
    Matlab入门学习(文件读写)
    Matlab入门学习(程序设计)
    IDEA中使用Maven下载依赖时报错:unable to find valid certification path to requested target
    全国县市区编码表
  • 原文地址:https://www.cnblogs.com/linjiqin/p/13643002.html
Copyright © 2020-2023  润新知