自定义局部过滤器
需求:在application.yml中对某个路由配置过滤器,该过滤器可以在控制台输出配置文件中指定名称的请求参数的值。
在gateway-server模块中编写过滤器工厂类MyParamGatewayFilterFactory
package com.icoding.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/** 自定义局部过滤器 */
@Component
public class MyParamGatewayFilterFactory extends
AbstractGatewayFilterFactory {
private static final String PARAM_KEY = "param";
/** 定义构造器(必须) */
public MyParamGatewayFilterFactory(){
super(Config.class);
}
/** 接收过滤器传进来的字段集合(可选) */
@Override
public List shortcutFieldOrder() {return Arrays.asList(PARAM_KEY);
}
/** 重写拦截方法(必须) */
@Override
public GatewayFilter apply(Config config) {return (exchange, chain) -> {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求参数 http://localhost:10010/api/user/get/2?name=zhangsan&age=30if (request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).forEach(value -> {
System.out.println(config.param + " = " + value);
});
}
// 放行return chain.filter(exchange);
};
}
/** 定义配置类,接收配置文件中的属性(必须) */
public static class Config {
private String param;
public String getParam() {return param;
}
public void setParam(String param) {
this.param = param;
}
}
}在gateway-server模块中修改application.yml配置文件
package com.icoding.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/** 自定义局部过滤器 */
@Component
public class MyParamGatewayFilterFactory extends
AbstractGatewayFilterFactory {
private static final String PARAM_KEY = "param";
/** 定义构造器(必须) */
public MyParamGatewayFilterFactory(){
super(Config.class);
}
/** 接收过滤器传进来的字段集合(可选) */
@Override
public List shortcutFieldOrder() {return Arrays.asList(PARAM_KEY);
}
/** 重写拦截方法(必须) */
@Override
public GatewayFilter apply(Config config) {return (exchange, chain) -> {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求参数 http://localhost:10010/api/user/get/2?name=zhangsan&age=30if (request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).forEach(value -> {
System.out.println(config.param + " = " + value);
});
}
// 放行return chain.filter(exchange);
};
}
/** 定义配置类,接收配置文件中的属性(必须) */
public static class Config {
private String param;
public String getParam() {return param;
}
public void setParam(String param) {
this.param = param;
}
}
}server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekaserver:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka测试访问
http://localhost:10010/api/user/1?name=admin 检查后台是否输出name和admin
http://localhost:10010/api/user/1?name2=admin 则是不会输出的。
自定义全局过滤器
需求:模拟一个登录的校验。基本逻辑:如果请求中有token参数,则认为请求有效,放行。
在gateway-server模块中编写全局过滤器类MyGlobalFilter
课堂代码:
package com.icoding.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/** 自定义局部过滤器 */
@Component
public class MyParamGatewayFilterFactory extends
AbstractGatewayFilterFactory {
private static final String PARAM_KEY = "param";
/** 定义构造器(必须) */
public MyParamGatewayFilterFactory(){
super(Config.class);
}
/** 接收过滤器传进来的字段集合(可选) */
@Override
public List shortcutFieldOrder() {return Arrays.asList(PARAM_KEY);
}
/** 重写拦截方法(必须) */
@Override
public GatewayFilter apply(Config config) {return (exchange, chain) -> {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求参数 http://localhost:10010/api/user/get/2?name=zhangsan&age=30if (request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).forEach(value -> {
System.out.println(config.param + " = " + value);
});
}
// 放行return chain.filter(exchange);
};
}
/** 定义配置类,接收配置文件中的属性(必须) */
public static class Config {
private String param;
public String getParam() {return param;
}
public void setParam(String param) {
this.param = param;
}
}
}server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekaserver:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekapackage com.icoding.filter;import org.apache.commons.lang.StringUtils;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.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;/** * 全局过滤器 */ @Component// @Order(1) : Ordered这个接口也可以使用注解来排序public class MyGlobalFilter implements GlobalFilter, Ordered { /*如果你有token就让他们访问,如果没有token,不让访问*/ @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("全局过滤器执行了。。。。。。。"); //获取参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); /* * String aa = ""; * String bb = " "; * String cc = null; * * 如果是isBlank 都是返回true * * */ if(StringUtils.isBlank(token)){ //为空,token没有值,阻止往下执行 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //设置返回的状态码 //不会继续往下执行了! return exchange.getResponse().setComplete(); } //放行 return chain.filter(exchange); } /*数值越小越先执行*/ @Override public int getOrder() { return 5; }}package com.icoding.filter;import org.apache.commons.lang.StringUtils;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.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;/** * 全局过滤器 */ @Component// @Order(1) : Ordered这个接口也可以使用注解来排序public class MyGlobalFilter implements GlobalFilter, Ordered { /*如果你有token就让他们访问,如果没有token,不让访问*/ @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("全局过滤器执行了。。。。。。。"); //获取参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); /* * String aa = ""; * String bb = " "; * String cc = null; * * 如果是isBlank 都是返回true * * */ if(StringUtils.isBlank(token)){ //为空,token没有值,阻止往下执行 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //设置返回的状态码 //不会继续往下执行了! return exchange.getResponse().setComplete(); } //放行 return chain.filter(exchange); } /*数值越小越先执行*/ @Override public int getOrder() { return 5; }}package com.icoding.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/** 自定义局部过滤器 */
@Component
public class MyParamGatewayFilterFactory extends
AbstractGatewayFilterFactory {
private static final String PARAM_KEY = "param";
/** 定义构造器(必须) */
public MyParamGatewayFilterFactory(){
super(Config.class);
}
/** 接收过滤器传进来的字段集合(可选) */
@Override
public List shortcutFieldOrder() {return Arrays.asList(PARAM_KEY);
}
/** 重写拦截方法(必须) */
@Override
public GatewayFilter apply(Config config) {return (exchange, chain) -> {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求参数 http://localhost:10010/api/user/get/2?name=zhangsan&age=30if (request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).forEach(value -> {
System.out.println(config.param + " = " + value);
});
}
// 放行return chain.filter(exchange);
};
}
/** 定义配置类,接收配置文件中的属性(必须) */
public static class Config {
private String param;
public String getParam() {return param;
}
public void setParam(String param) {
this.param = param;
}
}
}server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekaserver:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:# 默认过滤器,对所有路由生效
default-filters:# 添加响应头过滤器,添加一个响应头为name,值为admin
- AddResponseHeader=name,admin
routes:# 路由id,可以随意写
- id: user-service-route# 代理的服务地址;lb表示负载均衡(从eureka中获取具体服务)
uri: lb://user-service# 路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1# 自定义过滤器
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eurekapackage com.icoding.filter;import org.apache.commons.lang.StringUtils;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.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;/** * 全局过滤器 */ @Component// @Order(1) : Ordered这个接口也可以使用注解来排序public class MyGlobalFilter implements GlobalFilter, Ordered { /*如果你有token就让他们访问,如果没有token,不让访问*/ @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("全局过滤器执行了。。。。。。。"); //获取参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); /* * String aa = ""; * String bb = " "; * String cc = null; * * 如果是isBlank 都是返回true * * */ if(StringUtils.isBlank(token)){ //为空,token没有值,阻止往下执行 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //设置返回的状态码 //不会继续往下执行了! return exchange.getResponse().setComplete(); } //放行 return chain.filter(exchange); } /*数值越小越先执行*/ @Override public int getOrder() { return 5; }}package com.icoding.filter;import org.apache.commons.lang.StringUtils;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.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;/** * 全局过滤器 */ @Component// @Order(1) : Ordered这个接口也可以使用注解来排序public class MyGlobalFilter implements GlobalFilter, Ordered { /*如果你有token就让他们访问,如果没有token,不让访问*/ @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("全局过滤器执行了。。。。。。。"); //获取参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); /* * String aa = ""; * String bb = " "; * String cc = null; * * 如果是isBlank 都是返回true * * */ if(StringUtils.isBlank(token)){ //为空,token没有值,阻止往下执行 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //设置返回的状态码 //不会继续往下执行了! return exchange.getResponse().setComplete(); } //放行 return chain.filter(exchange); } /*数值越小越先执行*/ @Override public int getOrder() { return 5; }}package com.icoding.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/** 自定义全局过滤器 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("==全局过滤器MyGlobalFilter==");
String token = exchange.getRequest().getQueryParams().getFirst("token");if (StringUtils.isBlank(token)){
// 设置响应状态码: 401 未授权
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 返回响应完成return exchange.getResponse().setComplete();
}
// 放行return chain.filter(exchange);
}
@Override
public int getOrder() {
// 值越小越先执行return 1;
}
package com.icoding.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/** 自定义全局过滤器 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("==全局过滤器MyGlobalFilter==");
String token = exchange.getRequest().getQueryParams().getFirst("token");if (StringUtils.isBlank(token)){
// 设置响应状态码: 401 未授权
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 返回响应完成return exchange.getResponse().setComplete();
}
// 放行return chain.filter(exchange);
}
@Override
public int getOrder() {
// 值越小越先执行return 1;
}测试访问
访问 http://localhost:10010/api/user/1

访问 http://localhost:10010/api/user/1?token=admin


回复关键词
JUC 分布式限流 消息队列 alibaba JVM性能调优
看更多精彩教程
别忘了点个在看哦!转发那就太好了!
博客介绍了自定义局部和全局过滤器的实现。局部过滤器可在控制台输出配置文件指定名称的请求参数值,需编写过滤器工厂类并修改配置文件;全局过滤器模拟登录校验,请求含token参数则放行,需编写全局过滤器类,还给出了测试访问的示例。

2243

被折叠的 条评论
为什么被折叠?



