【经由网关层的接口返回的json数据中偶尔出现中文乱码的问题】

经由网关层的接口返回的json数据中偶尔出现中文乱码的问题

一、问题如下

页面出现乱码问题,且是偶发性的,不定时出现一次。

二、问题定位

  1. 排查编码格式: 前端、后台、数据库都为UTF-8,基本排除由于编码格式问题引起的乱码。
  2. 定位乱码位置: 前端页面显示乱码,应用服务日志正常,网关服务日志乱码。在网上查阅了一些资料,终于定位了问题就在gateway网关对response的处理上。

三、问题处理:

// 原代码
serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        DataBufferFactory bufferFactory = serverHttpResponse.bufferFactory();
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(serverHttpResponse) {
            @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(dataBuffers -> {
                        List<String> list = Lists.newArrayList();
                        dataBuffers.forEach(dataBuffer -> {
                            byte[] content = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(content);
                            DataBufferUtils.release(dataBuffer);
                            list.add(new String(content, Charset.forName("UTF-8")));
                        });
                        String resp = joiner.join(list);

                        byte[] uppedContent = new String(resp.getBytes(), Charset.forName("UTF-8")).getBytes();
                        return bufferFactory.wrap(uppedContent);
                    }));
                }
                return super.writeWith(body);
            }
        };

处理方法一: 结果报错

serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        DataBufferFactory bufferFactory = serverHttpResponse.bufferFactory();
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(serverHttpResponse) {
            @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(dataBuffers -> {
                        List<String> list = Lists.newArrayList();
                        dataBuffers.forEach(dataBuffer -> {
							DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
							DataBuffer join = dataBufferFactory.join(dataBuffers);
                            byte[] content = new byte[join.readableByteCount()];
                            join.read(content);
                            DataBufferUtils.release(join);
                            list.add(new String(content, Charset.forName("UTF-8")));
                        });
                        String resp = joiner.join(list);

                        byte[] uppedContent = new String(resp.getBytes(), Charset.forName("UTF-8")).getBytes();
                        return bufferFactory.wrap(uppedContent);
                    }));
                }
                return super.writeWith(body);
            }
        };


io.netty.util.IllegalReferenceCountException: refCnt: 0
        at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1489)
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
        |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.cloud.sleuth.instrument.web.TraceWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ HTTP POST "/*****/****/*****/*****?timestamp=****&nonce=****&signature=******" [ExceptionHandlingWebHandler]
Stack trace:
                at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1489)
                at io.netty.buffer.AbstractByteBuf.checkIndex(AbstractByteBuf.java:1418)
                at io.netty.buffer.PooledByteBuf.duplicateInternalNioBuffer(PooledByteBuf.java:194)
                at io.netty.buffer.PooledByteBuf.nioBuffer(PooledByteBuf.java:211)
                at io.netty.buffer.PooledSlicedByteBuf.nioBuffer(PooledSlicedByteBuf.java:89)
                at io.netty.buffer.AbstractByteBuf.nioBuffer(AbstractByteBuf.java:1232)
                at org.springframework.core.io.buffer.NettyDataBuffer.asByteBuffer(NettyDataBuffer.java:273)
                at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
                at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
                at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
                at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
                at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:546)
                at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
                at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:505)
                at org.springframework.core.io.buffer.DefaultDataBuffer.write(DefaultDataBuffer.java:308)
                at org.springframework.core.io.buffer.DefaultDataBufferFactory.lambda$join$0(DefaultDataBufferFactory.java:113)
                at java.util.ArrayList.forEach(ArrayList.java:1257)
                at org.springframework.core.io.buffer.DefaultDataBufferFactory.join(DefaultDataBufferFactory.java:113)
                at org.springframework.core.io.buffer.DefaultDataBufferFactory.join(DefaultDataBufferFactory.java:32)
                at com.taikang.grouppolicy.gateway.filter.AuthFilter$1.lambda$null$0(AuthFilter.java:168)
                at java.util.ArrayList.forEach(ArrayList.java:1257)
                at com.taikang.grouppolicy.gateway.filter.AuthFilter$1.lambda$writeWith$1(AuthFilter.java:166)
                at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100)
                at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onNext(ScopePassingSpanSubscriber.java:90)
                at reactor.core.publisher.FluxBuffer$BufferExactSubscriber.onComplete(FluxBuffer.java:179)

处理方法二: 目前正常

		serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        DataBufferFactory bufferFactory = serverHttpResponse.bufferFactory();
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(serverHttpResponse) {
            @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(dataBuffers -> {
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer join = dataBufferFactory.join(dataBuffers);
                        byte[] content = new byte[join.readableByteCount()];
                        join.read(content);
                        DataBufferUtils.release(join);
                        String resp=new String(content, Charset.forName("UTF-8"));

                        byte[] uppedContent = new String(resp.getBytes(), Charset.forName("UTF-8")).getBytes(StandardCharsets.UTF_8);
                        return bufferFactory.wrap(uppedContent);
                    }));
                }
                return super.writeWith(body);
            }
        };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值