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 filter(ServerWebExchange exchange, GatewayFilterChain chain) {

// 记录请求时间 和 ip

ServerHttpRequest request = exchange.getRequest();

if (null == request) {

exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);

return exchange.getResponse().setComplete();

}

List remoteAddressList = request.getHeaders().get("Remote_address");// 当走nginx转发时,获取此值 真实用户IP

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;

}

}

结束

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: