post请求在gateway打印日志内存遗漏

java 复制代码
@Component
public class CacheBodyGlobalFilter implements Ordered, GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        HttpMethod method = exchange.getRequest().getMethod();
        String contentType = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
        if (method == HttpMethod.POST || method == HttpMethod.PUT) {
//            if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)
//                    || MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(contentType)) {
            if (StrUtil.isNotBlank(contentType) && contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
                return DataBufferUtils.join(exchange.getRequest().getBody())
                        .flatMap(dataBuffer -> {
                            byte[] bytes = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(bytes);
                            //解决内存泄露问题
                            DataBufferUtils.release(dataBuffer);
                            ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                    exchange.getRequest()) {
                                @Override
                                public Flux<DataBuffer> getBody() {
                                    return Flux.defer(() -> {
                                        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
                                        DataBufferUtils.retain(buffer);
                                        return Mono.just(buffer);
                                    });
                                }
                            };

                            return chain.filter(exchange.mutate().request(mutatedRequest).build());
                        });
            }
        }
        return chain.filter(exchange);
    }

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

上述这段代码就是解决内存遗漏,一定写上

复制代码
DataBufferUtils.release(dataBuffer);

如何打印, 在GlobalFilter实现类

java 复制代码
/**
     * 从Flux<DataBuffer>中获取字符串的方法
     *
     * @return 请求体
     */
    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest, String path) {
        String contentType = serverHttpRequest.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
        log.info("contentType:{};path:{}", contentType, path);
        if (StrUtil.isNotBlank(contentType) && contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
            //获取请求体
            Flux<DataBuffer> body = serverHttpRequest.getBody();
            AtomicReference<String> bodyRef = new AtomicReference<>();
            body.subscribe(buffer -> {
                CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
                DataBufferUtils.release(buffer);
                bodyRef.set(charBuffer.toString());
            });
            return bodyRef.get();
        }
        return null;
    }
相关推荐
雨中飘荡的记忆38 分钟前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌3 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊4 小时前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang4 小时前
用六边形架构与整洁架构对比是伪命题?
java·架构
Ray Liang6 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Java水解6 小时前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
SimonKing10 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean10 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven9711 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java
皮皮林55121 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java