Spring Cloud Gatewat 中内置很多的路由过滤工厂,我们也可以根据实际应用场景自定义路由过滤器工厂。
GatewayFilter是网关中提供的一种过滤器,可以允许以某种方式修改请求进来的 http 请求或返回的 http 响应。路由过滤器主要作用于需要处理的特定路由。 官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
Spring Cloud Gateway 提供了很多种类的过滤器工厂,过滤器的实现类将近二十多个。总得来说,可以分为七类: Header 、 Parameter 、 Path 、 Status 、 Redirect 跳转、 Hytrix 熔断和 RateLimiter 。
2、添加请求头AddRequestHeaderGatewayFilterFactory作用:给匹配上的请求添加 header参数。
需求:给所有进入 app-user微服务的请求添加一个请求头(k-v):app-Request-arg=myHeaderValue。
我们只需要修改 gateway服务的 application.yml文件,添加路由过滤即可。
#配置 gateway网关
gateway:
#设置路由:路由id、路由到微服务的uri、断言
routes:
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
- Path=/app-user/user/**
filters:
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
app-user微服务代码:
@RequestMapping(value = "/getRequestHeader/{id}")
public R getRequestHeader(@PathVariable("id") Integer id, HttpServletRequest request) {
log.info("根据userId:" + id + "查询订单信息");
String header = request.getHeader("app-Request-arg");
log.info("gateWay获取请求头app-Request-arg的值:" + header);
return R.ok(header);
}
@RequestMapping(value = "/getRequestHeader2/{id}")
public R getRequestHeader2(@PathVariable("id") Integer id, @RequestHeader("app-Request-arg") String header) {
log.info("根据userId:" + id + "查询订单信息");
log.info("gateWay获取请求头app-Request-arg的值:" + header);
return R.ok(header);
}
访问:http://localhost:18088/app-user/user/getRequestHeader/1
AddRequestParameterGatewayFilterFactory作用:给匹配上的请求路由添加参数。
gateway服务的 application.yml文件,添加路由过滤:
#配置 gateway网关
gateway:
#设置路由:路由id、路由到微服务的uri、断言
routes:
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
- Path=/app-user/user/**
filters:
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
- AddRequestParameter=app-RequestParam-arg, zhaoZilong # 添加请求参数
app-user微服务代码:
@RequestMapping(value = "/getRequestParameter/{id}")
public R getRequestParameter(@PathVariable("id") Integer id, HttpServletRequest request, @RequestParam("app-RequestParam-arg") String param) {
log.info("根据userId:" + id + "查询订单信息");
String header = request.getHeader("app-Request-arg");
log.info("gateWay获取请求头app-Request-arg的值:" + header);
log.info("gateWay获取请求参数app-RequestParam-arg的值:" + param);
return R.ok(param);
}
AddResponseHeaderGatewayFilterFactory作用:给网关返回的响应数据中添加header。
gateway服务的 application.yml文件,添加路由过滤:
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
- Path=/app-user/user/**
filters:
# 删除前缀:1代表去除第一个路径
# - StripPrefix=1
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
- AddRequestParameter=app-RequestParam-arg, zhaoZilong # 添加请求参数
- AddResponseHeader=app-response-header, addResponseHeader_zhaoyun # 添加响应Header
StripPrefixGatewayFilterFactory作用:针对请求的 url的,Gateway会去除url前缀。
gateway服务的 application.yml文件,添加路由过滤:
注意:
数字代表去除path的第几个路径,从1开始。
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
- Path=/app-api/app-user/user/**
filters:
# 去除url前缀:1代表去除第一个路径
- StripPrefix=1
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
- AddRequestParameter=app-RequestParam-arg, zhaoZilong # 添加请求参数
- AddResponseHeader=app-response-header, addResponseHeader_zhaoyun # 添加响应Header
访问之前的URL:http://localhost:18088/app-user/user/getRequestParameter/1 。404 报错。
所以,我们对外浏览器访问的URL为:http://localhost:18088/app-api/app-user/user/getRequestParameter/1。
Gateway内部路由的url:http://localhost:18088/app-user/user/getRequestParameter/1。即路由匹配 uri: lb://app-user。
PrefixPathGatewayFilterFactory作用: 与 StripPrefixGatewayFilterFactory 相反,作用是增加url前缀。
gateway服务的 application.yml文件,添加路由过滤:
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
# - Path=/app-api/app-user/user/**
- Path=/user/**
filters:
# 去除url前缀:1代表去除第一个路径
# - StripPrefix=1
# 增加url前缀
- PrefixPath=/app-user
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
- AddRequestParameter=app-RequestParam-arg, zhaoZilong # 添加请求参数
- AddResponseHeader=app-response-header, addResponseHeader_zhaoyun # 添加响应Header
访问:http://localhost:18088/user/getRequestParameter/1
当请求因大小而被拒绝时,RequestSize GatewayFilter工厂将响应状态设置为413 Payload Too Large,并附加一个头错误消息。
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
超过5M的请求会返回413错误。
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
8、对所有请求添加过滤器
对所有请求添加过滤器,可以使用 spring.cloud.gateway.default-filters
指定。或者使用全局过滤器。
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
更多过滤器工厂配置,查看官方文档。
二、自定义过滤器工厂 1、创建自定义过滤器工厂在 Gateway服务中,创建自定义过滤器工厂类继承 AbstractNameValueGatewayFilterFactory
,并交给 Spring管理。
注意:
我们自定义类的名称必须以 GatewayFilterFactory结尾。
@Component
@Slf4j
public class AddAppCheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
/**
* 参考 AbstractNameValueGatewayFilterFactory类的子类。
* @param config
* @return
*/
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter(){
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取信息
System.out.println("调用 AppCheckAuthGatewayFilterFactory -> " + config.getName() + ":" + config.getValue());
// TODO
return chain.filter(exchange);
}
@Override
public String toString() {
return GatewayToStringStyler.filterToStringCreator(AddAppCheckAuthGatewayFilterFactory.this).append(config.getName(), config.getValue()).toString();
}
};
}
}
# app-user服务路由配置
- id: app-user
uri: lb://app-user
predicates:
- Path=/app-api/app-user/user/**
filters:
# 去除url前缀:1代表去除第一个路径
- StripPrefix=1
- AddRequestHeader=app-Request-arg, myHeaderValue #添加请求头
- AddRequestParameter=app-RequestParam-arg, zhaoZilong # 添加请求参数
- AddResponseHeader=app-response-header, addResponseHeader_zhaoyun # 添加响应Header
- AddAppCheckAuth=myauth-token, 赵云666 #自定义过滤器工厂
访问:http://localhost:18088/app-api/app-user/user/getRequestParameter/1
– 求知若饥,虚心若愚。