spring-cloud-gateway 功能-解析请求的中的请求参数

spring-cloud-gateway 功能-解析请求的中的请求参数

基于webflux

场景

当我们要进行接口签名验证的时候,就会获取request中的请求参数,特别是 获取完body数据的时候,转发给业务系统时,发现这个请求中的body不能再用了,所以需要利用request, 即将原始的request进行缓存

RequestParamExtractFilter

缓存 request, 顺序要排在过滤器比较前面!!

public class RequestParamExtractFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        HttpHeaders headers = request.getHeaders();
        MediaType contentType = headers.getContentType();

        //如果是上传请求
        if (contentType != null && contentType == MediaType.MULTIPART_FORM_DATA) {
            //如果是上传接口则不校验
            return chain.filter(exchange);
        }

        RequestParamContext context = new RequestParamContext();
        context.setMethod(request.getMethodValue());
        context.setPath(request.getPath().value());
        //仅获取 uri 上 query param
        //getQueryParams:
        //1.get 请求url参数
        //2.post 请求url上带的参数
        //3.获取不了body 请求参数
        Map<String, String> queryParams = request.getQueryParams().toSingleValueMap();
        context.setQueryParams(queryParams);
        if (contentType != null) {
            //如果仅仅只有地址栏上有参数,则contentType为空
            context.setContentType(MediaType.toString(Arrays.asList(contentType)));
        }
        if (context.getMethod().equals(HttpMethod.POST.name()) && headers.getContentLength() > 0) {
            return cacheBody(exchange, chain, context);
        }
        RequestContextUtil.setRequestParamContext(exchange, context);
        RequestContextUtil.logRequest(context,log);

        return chain.filter(exchange);
    }

    public Mono<Void> cacheBody(ServerWebExchange exchange, GatewayFilterChain chain, RequestParamContext context) {
        return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {
            //引用+1
            DataBufferUtils.retain(dataBuffer);
            DataBuffer tmpDataBuffer = dataBuffer.slice(0, dataBuffer.readableByteCount());
            byte[] bytes = new byte[tmpDataBuffer.readableByteCount()];
            tmpDataBuffer.read(bytes);
            // 将复制出来的tmpDataBuffer的计数器减少2,这个的同时也会将原始ataBuffer减少2
            String body = new String(bytes, StandardCharsets.UTF_8);
            DataBufferUtils.release(tmpDataBuffer);
            context.setBody(body);
            RequestContextUtil.setRequestParamContext(exchange, context);
            RequestContextUtil.logRequest(context, log);
            return chain.filter(exchange.mutate().request(decorateRequest(exchange, dataBuffer)).build());
        });
    }

    private ServerHttpRequest decorateRequest(ServerWebExchange exchange, DataBuffer dataBuffer) {
        return new ServerHttpRequestDecorator(exchange.getRequest()) {
            @Override
            public Flux<DataBuffer> getBody() {
                return Flux.just(dataBuffer);
            }
        };
    }


    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE + 100;
    }
}

RequestParamContext

@Data
public class RequestParamContext {

    /**
     * url 上的请求参数,不包含 请求 body 数据
     */
    private Map<String, String> queryParams;
    /**
     * 请求方法
     */
    private String method;
    /**
     * 请求类型
     */
    private String contentType;

    /**
     * body 参数
     *
     * 1.json:{a:b,c:d}
     * 2.xxx-form: a=b&c=d
     *
     */
    private String body;

    /**
     * 请求路径,除queryParams
     */
    private String path;
}

业务系统 cloud-user

GetController
@RestController
@Slf4j
public class GetController {

    @GetMapping("/get")
    public String get(GetParam param) {
        log.info("param:{}", JSON.toJSONString(param));
        return "get";
    }

    @GetMapping("/get/{id}")
    public String get(@PathVariable("id") Integer id, GetParam param) {
        param.setId(id);
        log.info("param:{}", JSON.toJSONString(param));
        return "get";
    }
}
PostController
@RestController
@Slf4j
public class PostController {

    @PostMapping("/post")
    public GetParam post(GetParam param) {
        log.info("param:{}", JSON.toJSONString(param));
        return param;
    }

    @PostMapping("/post/{id}")
    public GetParam postPath(@PathVariable("id") Integer id, GetParam param) {
        param.setId(id);
        log.info("param:{}", JSON.toJSONString(param));
        return param;
    }

    @PostMapping("/post/body")
    public GetParam postBody(@RequestBody GetParam param) {
        log.info("param:{}", JSON.toJSONString(param));
        return param;
    }

}
GetParam
@Data
public class GetParam {

    private String name;
    private Integer age;

    private Integer id;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ruoyi Cloud 是基于 Spring Cloud 和 Alibaba Nacos 的微服务框架,主要用于快速搭建分布式微服务架构。以下是 Ruoyi Cloud 的主要特点和功能: 1. 服务注册与发现:Ruoyi Cloud 使用 Alibaba Nacos 实现服务的注册、发现和配置管理,可以方便地实现服务间的通信和协作。 2. 负载均衡:Ruoyi Cloud 集成了 Ribbon 负载均衡组件,可以根据配置策略将请求分发到多个服务实例上,提高系统的性能和可用性。 3. 服务容错保护:Ruoyi Cloud 使用 Hystrix 实现服务的容错保护,当某个服务出现故障或超时时,可以快速降级或熔断,保证系统的稳定性。 4. 服务网关:Ruoyi Cloud 基于 Spring Cloud Gateway 实现了统一的服务网关,可以对外部请求进行路由、过滤和安全控制,提供了统一的访问入口。 5. 分布式配置心:Ruoyi Cloud 使用 Alibaba Nacos 集成了分布式配置心,可以实时管理应用程序的配置信息,支持动态刷新配置,方便进行系统运维和管理。 6. 分布式链路追踪:Ruoyi Cloud 集成了 SkyWalking 分布式链路追踪系统,可以对微服务间的调用进行监控和跟踪,方便分析和解决系统性能问题。 总结来说,Ruoyi Cloud 是一个基于 Spring Cloud 和 Alibaba Nacos 的微服务框架,提供了服务注册与发现、负载均衡、容错保护、服务网关、分布式配置心和链路追踪等功能,帮助开发人员快速搭建分布式微服务架构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值