Spring Cloud Gateway請(qǐng)求參數(shù)中文偶爾部分亂碼

現(xiàn)象

多個(gè)接口的請(qǐng)求參數(shù)中文偶爾部分亂碼,亂碼位置不固定

分析

  1. 根據(jù)日志分析,參數(shù)在達(dá)到應(yīng)用服務(wù)時(shí)亂碼,在應(yīng)用服務(wù)前還有Nginx和網(wǎng)關(guān),初步猜測(cè)網(wǎng)關(guān)出問(wèn)題的可能性較大
  2. 部分亂碼,估計(jì)是字節(jié)級(jí)別的處理問(wèn)題,在網(wǎng)關(guān)項(xiàng)目里全局搜索streambyte。經(jīng)過(guò)排查,在一處代碼出現(xiàn)byte轉(zhuǎn)字符串處理,代碼如下
@Override
public Flux<DataBuffer> getBody()
{
    Flux<DataBuffer> body = super.getBody();
    return body.map(dataBuffer -> {
        byte[] content = new byte[dataBuffer.readableByteCount()];
        dataBuffer.read(content);
        DataBufferUtils.release(dataBuffer);
        String bodyStr = new String(content, StandardCharsets.UTF_8);
        // 防xss攻擊過(guò)濾
        bodyStr = EscapeUtil.clean(bodyStr);
        // 轉(zhuǎn)成字節(jié)
        byte[] bytes = bodyStr.getBytes();
        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
        buffer.write(bytes);
        return buffer;
    });
}
  1. 當(dāng)請(qǐng)求體過(guò)大時(shí),網(wǎng)關(guān)會(huì)對(duì)請(qǐng)求體進(jìn)行切割,切分為多個(gè)字節(jié)數(shù)組,一個(gè)中文字符占2~3個(gè)字節(jié),如果切割數(shù)組時(shí)恰巧將一個(gè)中文的多個(gè)字節(jié)切分到2個(gè)數(shù)組中(一部分前,一部分后),再將切分后的字節(jié)數(shù)組轉(zhuǎn)字符串時(shí),就會(huì)出現(xiàn)亂碼問(wèn)題。

解決

修改這部分代碼如下

@Override
public Flux<DataBuffer> getBody()
{
    Flux<DataBuffer> body = super.getBody();
    return body.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 bodyStr = new String(content, StandardCharsets.UTF_8);
        // 防xss攻擊過(guò)濾
        bodyStr = EscapeUtil.clean(bodyStr);
        // 轉(zhuǎn)成字節(jié)
        byte[] bytes = bodyStr.getBytes();
        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
        buffer.write(bytes);
        return buffer;
    });
}

如何復(fù)現(xiàn)

知道問(wèn)題問(wèn)題為什么出現(xiàn),就容易復(fù)現(xiàn)了,只需要將請(qǐng)求體多塞點(diǎn)中文,中文越多,請(qǐng)求體越大,越容易復(fù)現(xiàn)。

后記

項(xiàng)目作者也修復(fù)了這個(gè)問(wèn)題:修復(fù)響應(yīng)體過(guò)大出現(xiàn)的亂碼問(wèn)題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn),也就放棄了無(wú)數(shù)的可能。 ...
    yichen大刀閱讀 7,787評(píng)論 0 4
  • 公元:2019年11月28日19時(shí)42分農(nóng)歷:二零一九年 十一月 初三日 戌時(shí)干支:己亥乙亥己巳甲戌當(dāng)月節(jié)氣:立冬...
    石放閱讀 7,432評(píng)論 0 2
  • 年紀(jì)越大,人的反應(yīng)就越遲鈍,腦子就越不好使,計(jì)劃稍有變化,就容易手忙腳亂,亂了方寸。 “玩壞了”也是如此,不但會(huì)亂...
    玩壞了閱讀 2,335評(píng)論 2 1
  • 感動(dòng) 我在你的眼里的樣子,就是你的樣子。 相互內(nèi)化 沒(méi)有絕對(duì)的善惡 有因必有果 當(dāng)你以自己的價(jià)值觀幸福感去要求其他...
    周粥粥叭閱讀 1,740評(píng)論 1 5
  • 昨天考過(guò)了阿里規(guī)范,心里舒坦了好多,敲代碼也猶如神助。早早完成工作回家嘍
    常亞星閱讀 3,249評(píng)論 0 1

友情鏈接更多精彩內(nèi)容