13 自定义过滤器
1.自定义局部过滤器
需求:在application.yml中对某个路由配置过滤器,该过滤器可以在控制台输出配置文件中指定名称的请求参数的 值。
1.1 编写过滤器
在piziwang-gateway工程编写过滤器工厂类MyParamGatewayFilterFactory
package com.piziwang.gateway.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<MyParamGatewayFilterFactory.Config> {
static final String PARAM_NAME = "param";
public MyParamGatewayFilterFactory() {
super(Config.class);
}
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// http://localhost:10010/api/user/8?name=itcast config.param ==> name
//获取请求参数中param对应的参数名 的参数值
ServerHttpRequest request = exchange.getRequest();
if(request.getQueryParams().containsKey(config.param)){
request.getQueryParams().get(config.param).
forEach(value -> System.out.printf("------------局部过滤器--------%s = %s------", 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;
}
}
}
1.2 修改配置文件
server:
port: 10010
spring:
application:
name: api-gateway
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-MyName,piziwang
routes:
# 路由id,可以任意
- id: user-service-route
# 代理的服务地址:lb表示从eureka中获取具体服务
uri: lb://user-service
#路由断言,可以配置映射路径
predicates:
- Path=/api/user/**
filters:
#添加请求路径的前缀
#- PrefixPath=/user
# 表示过滤1个路径,2表示两个路径,以此类推
- StripPrefix=1
- MyParam=name
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
1.3 测试访问
注意:自定义过滤器的命名应该为:***GatewayFilterFactory
测试访问:http://localhost:10010/api/user/8?name=piziwang 检查后台是否输出name和piziwang;但是若访问 http://localhost:10010/api/user/8?name2=piziwang则是不会输出的。
2.自定义全局过滤器
需求:模拟一个登录的校验。基本逻辑:如果请求中有token参数,则认为请求有效,放行。
2.1编写全局过滤器类MyGlobalFilter
package com.piziwang.gateway.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<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("--------------全局过滤器MyGlobalFilter------------------");
String token = exchange.getRequest().getQueryParams().getFirst("token");
if(StringUtils.isBlank(token)){
//设置响应状态码为未授权
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
//值越小越先执行
return 1;
}
}
2.2 测试
访问 http://localhost:10010/api/user/8
结果:401错误
访问: http://localhost:10010/api/user/8?token=abc
结果:正常获取