有人会疑问,之前的默认过滤器不也是针对所有路由请求的吗?为什么又要有一个全局过滤器?答案很简单,因为之前的默认过滤器我们只能在配置文件里面配置一些Spring规定好的参数,但是如果我们有一个复杂的业务逻辑想要加到拦截的请求内呢,那之前的默认过滤器不就没有办法了。
1.认识全局过滤器
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。 区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。
public interface GlobalFilter { /** * 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理 * * @param exchange 请求上下文,里面可以获取Request、Response等信息,甚至往里面存个东西,取个东西都行,从请求进入网关开始,一直到结束为止,整个流程中都可以共享exchange对象,第一个参数就是让我们编写整个过滤器的业务逻辑的,你需要的信息里面都有 * @param chain 用来把请求委托给下一个过滤器 * @return {@code Mono<Void>} 返回标示当前过滤器业务结束 */ Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }
在filter中编写自定义逻辑,可以实现下列功能:
-
登录状态判断
-
权限校验
-
请求限流等
2.自定义全局过滤器
实例:定义全局过滤器,拦截请求,判断请求的参数是否有authorization且值为admin
实现:在gateway服务中定义一个过滤器
package cn.itcast.gateway.filters; import com.sun.org.apache.bcel.internal.generic.RET; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @author 温柔哥 * @create 2024-01-19 22:34 */ // @Order() // 过滤器有很多,根据这个顺序来决定谁先执行谁后执行,值越小越先,默认,也可通过实现Ordered接口来实现 @Component // 注入到Spring容器中 public class Authorization implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取请求参数 ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> params = request.getQueryParams(); // 2.获取参数中的 authorization 参数 String auth = params.getFirst("authorization"); // 从里面取出第一个匹配的 // 3.判断参数值是否等于 admin if("admin".equals(auth)) { // 4.是,放行 return chain.filter(exchange); } // 5.拦截 // 5.1.设置状态码 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); // 5.2.拦截请求 return exchange.getResponse().setComplete(); } /** * 等同于@order(-1)注解的功能 * @return */ @Override public int getOrder() { return -1; } }
测试:
如果不加参数的话
@总结
全局过滤器的作用是什么?
- 对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器的步骤?
- 实现GlobalFilter接口
- 添加@Order注解或实现Ordered接口
- 编写处理逻辑