当前位置: 首页 > article >正文

【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值

【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值

实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了。

1. 获取请求参数RequestBody

@Component
@Slf4j
@AllArgsConstructor
public class HttpRequestFilter implements GlobalFilter, Ordered {

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

        String method = request.getMethodValue();
        String contentType = request.getHeaders().getFirst("Content-Type");
        if ("POST".equals(method)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        try {
                            String bodyString = new String(bytes, "utf-8");
                            log.info(bodyString);//打印请求参数
                            exchange.getAttributes().put("POST_BODY", bodyString);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        DataBufferUtils.release(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });

                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .build());
                    });
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -200;
    }
}

获取请求响应值ResponseBody

POSTMAN工具请求里的gzip压缩头导致获取响应值一直乱码,解决gzip压缩后响应值获取

@Slf4j
@Component
public class HttpResponseFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().toString();
        ServerHttpResponse originalResponse = exchange.getResponse();
        System.out.println(originalResponse.isCommitted());
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();

        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {

                if (body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
                    return super.writeWith(fluxBody.buffer().map(dataBuffer -> {
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer join = dataBufferFactory.join(dataBuffer);
                        byte[] content = new byte[join.readableByteCount()];
                        join.read(content);
                        //释放掉内存
                        DataBufferUtils.release(join);
                        String s = new String(content, StandardCharsets.UTF_8);

                        List<String> strings = exchange.getResponse().getHeaders().get(HttpHeaders.CONTENT_ENCODING);
                        if (!CollectionUtils.isEmpty(strings) && strings.contains("gzip")) {
                            GZIPInputStream gzipInputStream = null;
                            try {
                                gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(content), content.length);
                                StringWriter writer = new StringWriter();
                                IOUtils.copy(gzipInputStream, writer, "UTF-8");
                                s = writer.toString();

                            } catch (IOException e) {
                                log.error("====Gzip IO error", e);
                            } finally {
                                if (gzipInputStream != null) {
                                    try {
                                        gzipInputStream.close();
                                    } catch (IOException e) {
                                        log.error("===Gzip IO close error", e);
                                    }
                                }
                            }
                        } else {
                            s = new String(content, StandardCharsets.UTF_8);
                        }
                        log.info("bodyString: {}", s);//打印请求响应值
                        return bufferFactory.wrap(content);
                    }));
                }
                return super.writeWith(body);
            }
        };
        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }

    @Override
    public int getOrder() {
        return -200;
    }
}

参考资料:https://www.jianshu.com/p/7890a4f89229?ivk_sa=1024320u


http://www.kler.cn/a/156763.html

相关文章:

  • 机器学习day3-KNN算法、模型调优与选择
  • zabbix监控端界面时间与服务器时间不对应
  • 10款PDF翻译工具的探索之旅:我的使用经历与工具特色!!
  • 2024 kali操作系统安装Docker步骤
  • 云原生-docker安装与基础操作
  • 【Qt】在 Qt Creator 中使用图片资源方法(含素材网站推荐)
  • vs查找与替换功能【在文件中查找】不显示任何结果
  • 【objectarx.net】加载线型文件
  • golang 解决ZWNBSP 空字符问题
  • 【Docker】Swarm的ingress网络
  • 绿色建筑革新,气膜球馆成为城市锻炼新热点
  • Python 流程控制
  • HTML5+CSS3+Vue小实例:浪漫的心形文字动画特效
  • FFmpeg在Centos服务器上离线安装(包含所需依赖)并实现拉取rtsp流与推送至rtmp服务器
  • c++学习第四讲---函数提高
  • 跟着Nature Communications学习Hisat-Trinity-PASA等分析流程
  • 在windows上使用多个版本的chrome(谷歌)浏览器
  • java语言中受检异常和非受检异常的区别是什么?
  • 免费百度SEO优化工具,百度SEO优化排名工具
  • 网络运维与网络安全 学习笔记2023.11.30
  • 基于Python Flask 的全流程全栈项目自己的实战心得
  • 《opencv实用探索·九》中值滤波简单理解
  • 鸿蒙开发:Stage模型开发-应用/组件级配置以及UIAbility组件初步使用【鸿蒙专栏-20】
  • informer辅助笔记:exp/exp_informer.py
  • 【2021研电赛】基于EAIDK310的视觉导航自动驾驶小车
  • 【C语言】扫雷小游戏初学者版