美文网首页
springcloud gateway自定义过滤器

springcloud gateway自定义过滤器

作者: wuqingfeng | 来源:发表于2022-06-12 16:12 被阅读0次

    自定义gateway filter

    实现自定义的Gateway Filter我们需要GatewayFilter、Ordered两个接口

    /**
     * 此过滤器功能为计算请求完成时间
     */
    public class MyFilter implements GatewayFilter, Ordered {
    
        private static final String ELAPSED_TIME_BEGIN = "elapsedTimeBegin";
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis());
            return chain.filter(exchange).then(
                    Mono.fromRunnable(() -> {
                        Long startTime = exchange.getAttribute(ELAPSED_TIME_BEGIN);
                        if (startTime != null) {
                            System.out.println(exchange.getRequest().getURI().getRawPath() + ": " + (System.currentTimeMillis() - startTime) + "ms");
                        }
                    })
            );
        }
    
        /*
        *过滤器存在优先级,order越大,优先级越低
        */
        @Override
        public int getOrder() {
            return Ordered.LOWEST_PRECEDENCE;
        }
    }
    
    

    定义好MyFilter以后,其需要跟Route绑定使用,不能在application.yml文件中配置使用

    @Bean
        public RouteLocator routeLocator(RouteLocatorBuilder builder) {
            return builder.routes().route(r ->
                    r.path("/aa")
                            //转发路由
                            .uri("http://localhost:8003/provider/test")
                            //注册自定义过滤器
                            .filters(new MyFilter())
                            //给定id
                            .id("user-service"))
                    .build();
        }
    
    

    自定义Gateway Filter Factory

    很多时候我们更希望在配置文件中配置Gateway Filter,所以我们可以自定义过滤器工厂实现。
    自定义过滤器工厂需要继承AbstractGatewayFilterFactory

    @Component
    public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {
    
        private static final Log logger = LogFactory.getLog(AuthorizeGatewayFilterFactory.class);
    
        private static final String AUTHORIZE_TOKEN = "token";
        private static final String AUTHORIZE_UID = "uid";
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        public AuthorizeGatewayFilterFactory() {
            super(Config.class);
            logger.info("Loaded GatewayFilterFactory [Authorize]");
        }
    
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList("enabled");
        }
    
        @Override
        public GatewayFilter apply(AuthorizeGatewayFilterFactory.Config config) {
            return (exchange, chain) -> {
                if (!config.isEnabled()) {
                    return chain.filter(exchange);
                }
    
                ServerHttpRequest request = exchange.getRequest();
                HttpHeaders headers = request.getHeaders();
                String token = headers.getFirst(AUTHORIZE_TOKEN);
                String uid = headers.getFirst(AUTHORIZE_UID);
                if (token == null) {
                    token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
                }
                if (uid == null) {
                    uid = request.getQueryParams().getFirst(AUTHORIZE_UID);
                }
    
                ServerHttpResponse response = exchange.getResponse();
                if (StringUtils.isEmpty(token) || StringUtils.isEmpty(uid)) {
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    return response.setComplete();
                }
                String authToken = stringRedisTemplate.opsForValue().get(uid);
                if (authToken == null || !authToken.equals(token)) {
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    return response.setComplete();
                }
                return chain.filter(exchange);
            };
        }
    
        public static class Config {
            // 控制是否开启认证
            private boolean enabled;
    
            public Config() {}
    
            public boolean isEnabled() {
                return enabled;
            }
    
            public void setEnabled(boolean enabled) {
                this.enabled = enabled;
            }
        }
    }
    

    在application.yml配置使用

    # 网关路由配置
    spring:
      cloud:
        gateway:
          routes:
          - id: user-service
            uri: http://localhost:8077/api/user/list
            predicates:
            - Path=/user/list
            filters:
            # 关键在下面一句,值为true则开启认证,false则不开启
            # 这种配置方式和spring cloud gateway内置的GatewayFilterFactory一致
            - Authorize=true
    

    自定义Global Filter

    实现自定义全局过滤器需要继承GlobalFilter和Ordered

    @Component
    public class MyGloablFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            System.out.println("1111111111111111");
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    

    相关文章

      网友评论

          本文标题:springcloud gateway自定义过滤器

          本文链接:https://www.haomeiwen.com/subject/wgggmrtx.html