Spring Gateway过滤器使用注入的Bean对象

最近项目从spring zuul切换到spring gateway,原来项目中用户登录权限存储在redis中,使用了StringRedisTemplate对redis操作。为了方便准备接拷贝验证部分代码。但在请求执行过滤器时候发现StringRedisTemplate为null。当时第一反应是Filter加载顺序问题,但随即想到,在过滤器执行的时候Bean已经在Spring容器中加载完成了(具体可以看spring源码,这里不做详述)。下面贴一下最初关键代码
1、yml中关键配置
在这里插入图片描述

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: hb-balance-server
          uri: lb://hb-balance-server
          predicates:
            - Path=/balance/**
          filters:
            - StripPrefix=0
            - Auth

2、将过滤器加载到容器中
在这里插入图片描述

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;

@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return new AuthGatewayFilter();
    }
}

3、实现过滤器权限验证
在这里插入图片描述

import cn.synline.gateway.server.redis.AuthRedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class AuthGatewayFilter implements GatewayFilter, Ordered {
    @Autowired
    private AuthRedisService authRedisService;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        MultiValueMap<String, HttpCookie>  cookieMultiValueMap = exchange.getRequest().getCookies();
        String token = CookieUtil.token(cookieMultiValueMap);
        String userInfo = authRedisService.loginUserInfo(token);
        log.info("token:{},userInfo:{}",token,userInfo);
        if (userInfo != null){
            return chain.filter(exchange);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }

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

系统运行时,authRedisService为null。因为过滤器对象是new 出来的,所以这个过滤器下是不能通过@Autowired获取容器对象
在这里插入图片描述
稍微调整一下,这个对象在初始化的时候我们从spring 容器中获得,代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;

@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Autowired
    private AuthGatewayFilter authGatewayFilter;
    @Override
    public GatewayFilter apply(Object config) {
        return authGatewayFilter;
    }
}

然后直接跑一下看效果
在这里插入图片描述
已经可以拿到对象了。OK了
在使用spring gateway的自定义过滤器时还需要注意,“AuthGatewayFilterFactory” 这个工厂名称要遵循Spring约定,我的过滤器在yml配置中名称为Auth。xxx + GatewayFilterFactory,XXX为过滤器名称

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
除了全局过滤器之外,Spring Cloud Gateway还提供了局部过滤器的功能,可以对某个路由进行特定的处理。 使用局部过滤器,需要在路由配置中添加一个filters属性,并且在该属性中指定过滤器的名称或者类名。例如: ```yaml spring: cloud: gateway: routes: - id: myRoute uri: http://localhost:8080 predicates: - Path=/myPath/** # 添加一个局部过滤器 filters: - MyLocalFilter ``` 上面的配置中,我们为名为myRoute的路由添加了一个局部过滤器MyLocalFilter,该过滤器可以是一个Bean的名称或者一个类的全限定名。如果是一个类的全限定名,则需要通过@Component或者@Bean注解将该类加入到Spring容器中。 在局部过滤器中,同样需要实现GatewayFilter接口,并且实现filter方法。在该方法中,可以对请求进行特定的处理,例如添加请求头、修改请求体等。 下面是一个示例代码: ```java @Component public class MyLocalFilter implements GatewayFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 在请求头中添加一个自定义的token exchange.getRequest().mutate().header("token", "myToken").build(); // 继续执行过滤器链 return chain.filter(exchange); } } ``` 在上面的代码中,我们实现了一个局部过滤器,将一个自定义的token添加到请求头中,并且继续执行过滤器链。在这个过程中,可以通过exchange对象获取到请求、响应等信息。 需要注意的是,局部过滤器只对指定的路由进行处理,如果需要对多个路由进行相同的处理,可以将该过滤器添加到多个路由的filters属性中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值