SpringCloud Gateway读取Request Body

1:我个人所了解到的有两种方式,都是利用路由谓词过滤器获取:

同样的获取方式

// 获取缓存里请求体的body值
 String requestBody = exchange.getAttribute("cachedRequestBodyObject");

1:在代码里使用RouteLocator

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

@Component
public class AccessLogFilter {

    @Bean
    public RouteLocator myRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                // 路由id随意指定,和其他路由id不重复即可
                .route("routeId", p -> p
                        // api-user 代表下游微服务的一级路由
                        .path("/api-user/account/save")
                        // 此处的 1 代表将上面的/api-user截取掉, 这样后面的路径就是下个微服务的请求接口(/account/save)
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class, String.class, (webExchange, originalBody) -> {
                                    if (originalBody != null) {
                                        webExchange.getAttributes().put("cachedRequestBodyObject", originalBody);
                                        return Mono.just(originalBody);
                                    } else {
                                        return Mono.empty();
                                    }
                                }))
                        // lb: 代表着路由到其他的微服务, service-user: 是你要路由的微服务启动后的服务名
                        .uri("lb://service-user"))
                .build();
    }

}

2:在配置文件里使用predicates

import org.springframework.stereotype.Component;
import java.util.function.Predicate;

/**
 * 是否记录请求体的body, 根据配置文件里的path进行生效
 *  配置文件里搜索 @requestBodyPredicate 定位到该路由规则
 */
@Component
public class RequestBodyPredicate implements Predicate {

    /**
     * 是否缓存 请求体里的body 值
     *
     * @param body 请求体里的对象
     * @return boolean  false: 不缓存, true: 缓存, 在下面的filter里获取方式: exchange.getAttribute("cachedRequestBodyObject");
     */
    @Override
    public boolean test(Object body) {
        return true;
    }
}
# 参考java代码里的注释
spring:
  cloud:
    gateway:
      routes:
        - id: routeId
          uri: lb://service-user
          predicates:
            - Path=/api-user/account/save
            # 使用该Factory,会将body自动放入到过滤器中
            - name: ReadBodyPredicateFactory
              args:
                inClass: "#{T(String)}" 
                # requestBodyPredicate 对应着 spring bean 的名称
                predicate: "#{@requestBodyPredicate}"
          filters:
            - StripPrefix=1

参考:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#modify-a-request-body-gatewayfilter-factory

你可能感兴趣的:(SpringCloud Gateway读取Request Body)