Spring cloud gateway 获取RequestBody
在gateway中获取请求的json 数据
文章目录
Spring cloud gateway 获取RequestBody环境一、自定义读取RequestBody的bean二、自定义根据数据判断是否继续路由的bean三、修改路由配置四、怎么获取创建全局过滤
结束
环境
项目开发所在环境
名称版本号spring cloud alibaba2021.0.4.0spring gateway3.1.6spring boot2.6.11
提示:以下是本篇文章正文内容,下面案例可供参考
一、自定义读取RequestBody的bean
此类主要继承 ReadBodyRoutePredicateFactory 一定要自己查看下此类
import org.springframework.cloud.gateway.handler.predicate.ReadBodyRoutePredicateFactory;
import org.springframework.stereotype.Component;
/**
* @ClassName JsonReadBodyRoutePredicate
* @Description gateway 中 读取 请求的jsonBody
* 这里是 将 请求数据中的json 放到 'cachedRequestBodyObject' 此属性中
* @Version 1.0
*/
@Component
public class JsonReadBodyRoutePredicate extends ReadBodyRoutePredicateFactory {
// 此类可重写,亦可不重写 ,根据自己需要
// 父类方法完全够我用的,所以不做改动
}
二、自定义根据数据判断是否继续路由的bean
继承Predicate 由于我们能的json 是字符串 所以是String类型
import org.springframework.stereotype.Component;
import java.util.function.Predicate;
/**
* @ClassName JsonRequestBody
* @Version 1.0
*/
@Component
public class JsonRequestBodyPredicate implements Predicate
/**
* @param reqJson 此json 为请求的json字符串
* @return 如果返回true则继续路由访问真正的接口,如果返回false 则不会路由
*/
@Override
public boolean test(String reqJson) {
// 这里可以根据 请求字符串 或者 自行添加 path 来判断是否需要继续路由
return true;
}
}
三、修改路由配置
(新增) 表示 需要添加的配置
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-server-route
uri: lb://user-server
predicates:
- Path=/user-api/**
- name: JsonReadBodyRoutePredicate # 新增 这里是(一)中定义的bean
args: # 新增
inClass: "java.lang.String" # 新增 这里要注意 springboot 2.6以后使用此写法
# inClass: "#{T(String)}" #spring boot 2.5(包含2.5)以下 使用此写法
predicate: "#{@jsonRequestBodyPredicate}" # 新增 这里是(二)中定义的bean
filters:
- StripPrefix=1
- name: Retry # Retry 为重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求
args:
retries: 3
status: 505
四、怎么获取
获取Json 中有2个地方 ,第一 :(二)中配置的bean 可直接获取json 第二:使用全局拦截器,然后从exchange中获取 第一种,自行debug 查看就好,主要说第二种
创建全局过滤
代码如下
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
/**
* @ClassName ElapseFilter
* @Description 计时过滤器--全局过滤器
* @Author [Miller-hw]
* @Version 1.0
*/
//全局过滤器必须实现两个接口:GlobalFilter、Ordered
//GlobalFilter是全局过滤器接口,实现类要实现filter()方法进行功能扩展
//Ordered接口用于排序,通过实现getOrder()方法返回整数代表执行当前过滤器的前后顺序
@Component
public class GatewayGlobalFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(GatewayGlobalFilter.class);
private static final String SERVICE_TIME_BEGIN = "serviceTimeBegin";
// 这个放我 我写了记录 接口耗时的方法 有其他需求自行填写
@Override
public Mono
// 记录请求时间 和 ip
ServerHttpRequest request = exchange.getRequest();
if (null == request) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
List
String remoteAddressStr = (null != remoteAddressList && !remoteAddressList.isEmpty()) ? remoteAddressList.get(0) : "empty";
exchange.getAttributes().put(SERVICE_TIME_BEGIN, System.currentTimeMillis());
// 如果需要获取请求头 ,只支持json,其他格式无法解析
// Object reqJson = exchange.getAttributes().get("cachedRequestBodyObject");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
long endTime = System.currentTimeMillis();
Long startTime = exchange.getAttribute(SERVICE_TIME_BEGIN);
Optional.ofNullable(startTime).ifPresent(l->{
String reqPath = request.getRemoteAddress()+"("+Optional.ofNullable(remoteAddressStr).orElse("empty")+")" + "|" + request.getPath() + "| cost " + (endTime - startTime) + "ms";
log.warn(reqPath);
});
}));
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
结束
精彩文章
大家都在找:
Java:java下载
spring:spring春天
spring boot:springboot框架图
发表评论