网关过滤器简介
网关过滤器是一个位于应用程序和底层服务之间的组件,它截取进出网络请求,并提供对请求和响应进行处理的机制。它可以在请求到达目标服务之前或响应返回给客户端之前拦截、修改或增强它们。
网关提供了31种,但每一种过滤器的作用都是固定的。**如果我们希望拦截请求,做自己的业务逻辑则没办法实现。这就引出了我们的Spring Gateway全局过滤器。**他可以实现过滤请求的时候按照自己的自己的业务逻辑进行路由的处理。
Gateway网关的过滤器分为两种,一种是局部过滤器,一种是全局过滤器。
在这里,全局过滤器的作用是处理一切进入网关的请求和微服务响应,GlobalFilter的逻辑需要自己写代码实现。
网关过滤器的作用
网关过滤器具有广泛的应用场景,包括但不限于以下方面:
安全性:通过身份验证、加密和防火墙等机制来保护应用程序和数据的安全。
访问控制:控制用户对资源的访问权限,确保只有经过授权的用户可以访问敏感信息。
缓存:缓存响应以减少对底层服务的请求次数,提高性能。
日志记录:记录请求和响应的详细信息,用于故障排除和监控。
负载均衡:将请求分发到多个后端服务,以提高可用性和吞吐量。
过滤器的生命周期
过滤器在 Java Servlet 规范中定义了其生命周期,生命周期涵盖了过滤器的创建、初始化、请求处理和销毁等不同阶段。下面从多个角度描述过滤器的生命周期。
创建和加载阶段:
在应用程序启动时,Web 容器会加载过滤器并创建其实例。过滤器的创建是由容器负责的,它会在需要的时候实例化过滤器对象。
初始化阶段:
过滤器在创建后会进行初始化操作。在过滤器初始化阶段,可以执行一些预备工作,如读取配置参数、建立数据库连接等。过滤器可以通过重写 init() 方法来实现自定义的初始化逻辑。该方法会在过滤器创建后立即调用一次。
请求处理阶段:
过滤器的主要功能是在请求到达目标资源之前或之后进行拦截和处理。在请求处理阶段,过滤器会拦截请求并执行自定义的逻辑,如身份验证、请求修改、日志记录等。过滤器通过实现 doFilter() 方法来定义自己的处理逻辑。在调用 doFilter() 方法之前,容器会首先调用过滤器的 init() 方法进行初始化。
过滤器链:
在请求处理阶段,如果应用程序中有多个过滤器,它们会形成一个过滤器链。过滤器链的顺序由过滤器在部署描述符中的配置顺序决定。每个过滤器都可以选择将请求传递给下一个过滤器或目标资源,或者在需要时中断请求链的传递。过滤器链的执行顺序是按照配置中的顺序依次执行的。
请求处理完成和响应返回阶段:
在过滤器链中的过滤器都完成了它们的处理逻辑后,请求会到达目标资源(例如 Servlet 或 JSP)。目标资源执行完毕后,响应会返回给过滤器链。此时,过滤器链中的过滤器可以对响应进行修改、处理或记录日志等操作。
销毁阶段:
当 Web 应用程序关闭或过滤器被卸载时,过滤器会进入销毁阶段。在销毁阶段,可以执行一些资源释放或清理操作,如关闭数据库连接、释放文件句柄等。过滤器通过重写 destroy() 方法来实现自定义的销毁逻辑。
过滤器的生命周期包括创建和加载、初始化、请求处理、过滤器链、请求处理完成和响应返回、销毁等阶段。在这些阶段中,过滤器负责拦截和处理请求,以实现自定义的逻辑。
实际应用示例
权限过滤器
@Component public class AuthorizationFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); //1、获取请求路径 String path = request.getPath().toString(); //不需要拦截的地址 if ("/test/test/TestController/test".equals(path) ) { return chain.filter(exchange); } //获取 String openId = request.getHeaders().getFirst("Authorization"); response.setStatusCode(HttpStatus.NOT_FOUND); return response.setComplete(); // // 继续链式调用,交给下一个拦截器处理 // return chain.filter(exchange); } @Override public int getOrder() { return 1; }
解析
GlobalFilter接口
public interface GlobalFilter { /** * 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理 * * @param exchange 请求上下文,里面可以获取Request、Response等信息 * @param chain 用来把请求委托给下一个过滤器 * @return {@code Mono<Void>} 返回标示当前过滤器业务结束 */ Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }
order接口
每一个过滤器都必须指定一个int类型的order值,order值越小,过滤器优先级越高,执行顺序越靠前。
两种方式:
实现order接口
方式二:在类上添加注解@Order
总结
网关过滤器是处理进出网络请求的重要组件,它们在Java中的实现通过javax.servlet.Filter接口提供了灵活和可扩展的方式。通过编写Java代码示例,我们展示了如何创建和使用网关过滤器,并介绍了过滤器链和过滤器的生命周期。
网关过滤器在现代网络应用程序中具有多种用途,包括提供安全性、访问控制、缓存、日志记录和负载均衡等功能。我们还提供了一些实际应用示例,如安全性过滤器、访问控制过滤器和日志记录过滤器,以展示网关过滤器在实际场景中的用法。
使用网关过滤器可以增加应用程序的安全性、性能和可扩展性。它们能够截取和处理进出网络请求,为开发人员提供了对请求和响应进行修改和增强的能力。通过适当配置和组织过滤器链,我们可以实现复杂的请求处理逻辑,并根据需要添加、删除或修改过滤器。
总之,网关过滤器是Java中强大的工具,为我们提供了处理网络请求的灵活性和控制能力。通过充分理解和应用网关过滤器的概念和技术,我们可以构建安全、高效和可靠的网络应用程序。