spring cloud gateway Response 修改bug

24 篇文章 0 订阅
10 篇文章 0 订阅

spring cloud gateway Response修改后,返回值中及个别字符乱码。

相信很多人接触了spring cloud gateway,但是少数人会真正把它直接用在项目上,我们的新项目快上线了,整个开发过程中遇到了很多问题,简单说一下感受,现阶段spring cloud gateway相关资料太少,很多东西查不到,很多时候需要自己去看源码自己去仿照源码重新去写,而且大坑往往更是查不到。

spring cloud gateway Response 修改并不被官方推荐,但是我们有一个需求,就是在网关内对某些特殊的字符进行替换,而且完全替换,相信这种需求很多人都遇到过,但是有N种实现方式,而我想到的最简单的方式就是在网关内对response进行修改替换了,这也是为大坑埋下了伏笔。

 

上图看现象:

一包返回值中仅出现一个中文字符乱码

但是多个接口中出现了同样的现象!!!

又不是每个接口都发生问题。

 

给人的感受,这不像是编码问题,感觉好像是返回值因为数据量过长,在处理时进行拆分处理的过程中遇到了问题。

 

但是后来,通过对比原始数据的字节数组发现了问题。

可以看出,原始返回值仅经过转换未做任何处理时,已经出现了问题,这是字节数组,最后几位发生了变化。

 

这个问题感觉好像还是字节数组和字符串相互转换时发生了问题。

 

上代码:(这是已经解决问题了的代码)

ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (HttpStatus.OK.equals(getStatusCode()) && body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {

                        StringBuffer stringBuffer = new StringBuffer();
                        dataBuffers.forEach(dataBuffer -> {
                            byte[] content = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(content);
                            DataBufferUtils.release(dataBuffer);
                            String tempStr = new String(content, Charset.forName("ISO_8859_1"));
                            stringBuffer.append(tempStr);
                        });

                        String str = new String(stringBuffer);
                        String fileKey = "\":\"" + Const.DATA_BASE_FILE_URL_HEAD + Const.M00;
                        if (str.contains(fileKey)) {
                            //修改
                            String value = "\":\"" + Const.SYSTEMS_FILE_URL_HEAD + Const.DATA_BASE_FILE_URL_HEAD + Const.M00;
                            str = str.replaceAll(fileKey, value);
                        }

                        byte[] content = str.getBytes(Charset.forName("ISO_8859_1"));
                        return bufferFactory().wrap(content);
                    }));
                }
                // if body is not a flux. never got there.
                return super.writeWith(body);
            }
        };

百度一大堆都是写的UTF-8,其实这是有问题的。

由于 UTF-8 是多字节编码,需要用多个字节来表示一个字符的编码,所以也就出现了在转换之后 byte[] 数组长度、内容不一致的情况。而 ISO-8859-1 编码是单字节编码,所以使用该编码就不会出现问题。

因此这里一定要用ISO-8859-1编码,百度一大堆却没一个对的,相信大多数都是demo,并没有发现问题。

 

参考:

https://blog.csdn.net/qq_27760433/article/details/78327328

 

一定要注意字节数组的处理!!!

 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ah_ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值