国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

spring cloud gateway 源碼解析(3)記錄請(qǐng)求參數(shù)及返回的json

MangoGoing / 3372人閱讀

摘要:一開(kāi)始搜索讀取參數(shù)的文章,方法大多是從里讀一次,轉(zhuǎn)成字符串,然后再把字符串轉(zhuǎn)成重新放到里,如上面的方法我試過(guò)可以,但是是的時(shí)候會(huì)報(bào)錯(cuò)不知道是不是我姿勢(shì)不對(duì)。

(1)一開(kāi)始搜索讀取參數(shù)的文章,方法大多是從body里讀一次DataBuffer,轉(zhuǎn)成字符串,然后再把字符串轉(zhuǎn)成DataBuffer重新放到body里,如:
http://www.cnblogs.com/cafeba...

(2)

上面的方法我試過(guò)可以,但是Content-Type是multipart/form-data的時(shí)候會(huì)報(bào)錯(cuò)
java.lang.IllegalStateException: Only one connection receive subscriber allowed.
不知道是不是我姿勢(shì)不對(duì)。
而且如果我們?cè)诖淼降谌椒?wù)的時(shí)候才讀取body,這樣效率應(yīng)該會(huì)高一些
看NettyRoutingFilter類(lèi)里的filter方法
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ·······

        Mono responseMono = this.httpClient.request(method, url, req -> {
            final HttpClientRequest proxyRequest = req.options(NettyPipeline.SendOptions::flushOnEach)
                    .headers(httpHeaders)
                    .chunkedTransfer(chunkedTransfer)
                    .failOnServerError(false)
                    .failOnClientError(false);

            if (preserveHost) {
                String host = request.getHeaders().getFirst(HttpHeaders.HOST);
                proxyRequest.header(HttpHeaders.HOST, host);
            }

            if (properties.getResponseTimeout() != null) {
                proxyRequest.context(ctx -> ctx.addHandlerFirst(
                        new ReadTimeoutHandler(properties.getResponseTimeout().toMillis(), TimeUnit.MILLISECONDS)));
            }

            return proxyRequest.sendHeaders() 
                    //這里的是ReactorServerHttpRequest調(diào)用了getBody()方法,
                    //所以我們只要重寫(xiě)ReactorServerHttpRequest的getbody方法,加上我們讀取的邏輯就行了,
                    //gateway給我們提供了裝飾類(lèi)ServerHttpRequestDecorator,我們只需把過(guò)濾器的優(yōu)先級(jí)設(shè)置高于NettyRoutingFilter(實(shí)際他已經(jīng)是倒數(shù)第二的優(yōu)先級(jí)了),且把ReactorServerHttpRequest替換成ServerHttpRequestDecorator就行了
                    .send(request.getBody().map(dataBuffer ->
                            ((NettyDataBuffer) dataBuffer).getNativeBuffer()));
        });
給個(gè)stackoverflow的偽代碼
ServerHttpRequestDecorator decoratedRequest = new ServerHttpRequestDecorator(request) {
             @Override
            public Flux getBody() { 
                 StringBuilder sb=new StringBuilder();
                  return  super.getBody().map(dataBuffer -> {
                    // probably should reuse buffers 
                    byte[] content = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(content);
                    byte[] uppedContent = new String(content, Charset.forName("UTF-8")).toUpperCase().getBytes();
                    return bufferFactory.wrap(uppedContent);
                }) ; 
            }
};

            //再說(shuō)說(shuō)記錄返回的json,在NettyRoutingFilter類(lèi)的154行,請(qǐng)求第三方服務(wù)反回后,
            // Defer committing the response until all route filters have run
            // Put client response as ServerWebExchange attribute and write response later NettyWriteResponseFilter
            //注釋說(shuō)了把返回結(jié)果放進(jìn)ServerWebExchange 的參數(shù)里了,并且在NettyWriteResponseFilter讀取
            exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);


看NettyWriteResponseFilter的讀取代碼,
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       return chain.filter(exchange).then(Mono.defer(() -> {
           //拿出NettyRoutingFilter放進(jìn)去的Response 
            HttpClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);

            if (clientResponse == null) {//空的就不過(guò)直接到下一個(gè)過(guò)濾器
                return Mono.empty();
            }
            log.trace("NettyWriteResponseFilter start");
            ServerHttpResponse response = exchange.getResponse();

            NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory();
            //TODO: what if it"s not netty

            final Flux body = clientResponse.receive()
                    .retain() //TODO: needed?
                    .map(factory::wrap);

            MediaType contentType = null;
            try {
                contentType = response.getHeaders().getContentType();
            } catch (Exception e) {
                log.trace("invalid media type", e);
            }
            //判斷contentType是不是text/event-stream或者application/stream+json
            //反正上面兩種類(lèi)型的結(jié)果我們肯定不用記錄,所以我們重寫(xiě)response的writeWith方法就好,
            //跟上面一樣gateway也提供了個(gè)裝飾器類(lèi)ServerHttpResponseDecorator
            return (isStreamingMediaType(contentType) ?
                    response.writeAndFlushWith(body.map(Flux::just)) : response.writeWith(body));
        }));
    }
上stackoverflow的偽代碼
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
      ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
        @Override
        public Mono writeWith(Publisher body) {
            if (body instanceof Flux) {
                Flux fluxBody = (Flux) body;
                return super.writeWith(fluxBody.map(dataBuffer -> {
                    // probably should reuse buffers 
                    byte[] content = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(content);
                    byte[] uppedContent = new String(content, Charset.forName("UTF-8")).toUpperCase().getBytes();
                    return bufferFactory.wrap(uppedContent);
                }));
            }
            return super.writeWith(body); // if body is not a flux. never got there.
        }           
      }; 

參考:
https://stackoverflow.com/que...

該如果返回的數(shù)據(jù)長(zhǎng)度很長(zhǎng)的話(huà),數(shù)據(jù)可能會(huì)讀不完全,如果出現(xiàn)讀取時(shí)截取了中文字符,導(dǎo)致長(zhǎng)度變多1位,進(jìn)而json的右括號(hào)消失,也可參考下面鏈接
參考解決方案:
https://stackoverflow.com/que...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/77398.html

相關(guān)文章

  • Spring Cloud Gateway修改請(qǐng)求和響應(yīng)body內(nèi)容

    摘要:歡迎訪(fǎng)問(wèn)我的歡迎訪(fǎng)問(wèn)我的內(nèi)容所有原創(chuàng)文章分類(lèi)匯總及配套源碼,涉及等本篇概覽本篇概覽作為實(shí)戰(zhàn)系列的第九篇,咱們聊聊如何用修改原始請(qǐng)求和響應(yīng)內(nèi)容,以及修改過(guò)程中遇到的問(wèn)題首先是修改請(qǐng)求,如下圖,瀏覽器是請(qǐng)求發(fā)起方,真實(shí)參數(shù)只有,經(jīng)過(guò)網(wǎng)關(guān)時(shí)被塞歡迎訪(fǎng)問(wèn)我的GitHubhttps://github.com/zq2599/blog_demos內(nèi)容:所有原創(chuàng)文章分類(lèi)匯總及配套源碼,涉及Java、Dock...

    ivyzhang 評(píng)論0 收藏0
  • spring cloud gateway 源碼解析(1)整體流程

    摘要:公司要做自己的網(wǎng)關(guān),于是先把的過(guò)了一遍,然后把源碼在看了一遍,這樣公司的需求就搞定了。包括動(dòng)態(tài)路由,多緯度限流,記錄請(qǐng)求參數(shù)及返回參數(shù)也可修改。至此,流程就走完了。 公司要做自己的網(wǎng)關(guān),于是先把github的issue過(guò)了一遍,然后把gateway源碼在看了一遍,這樣公司的需求就搞定了。包括動(dòng)態(tài)路由,多緯度限流,記錄請(qǐng)求參數(shù)及返回參數(shù)(也可修改)。先從請(qǐng)求進(jìn)入網(wǎng)關(guān)說(shuō)起吧: 請(qǐng)求先進(jìn)...

    miqt 評(píng)論0 收藏0
  • SpringCloud升級(jí)之路2020.0.x版-41. SpringCloudGateway 基本

    摘要:將請(qǐng)求封裝成將請(qǐng)求封裝成的接口定義是但是最外層傳進(jìn)來(lái)的參數(shù)是和,需要將他們封裝成,這個(gè)工作就是在中做的。其實(shí)主要任務(wù)就是將各種參數(shù)封裝成除了和本次請(qǐng)求相關(guān)的和,還有會(huì)話(huà)管理器,編碼解碼器配置,國(guó)際化配置還有用于擴(kuò)展。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent接下來(lái),將進(jìn)入我們升級(jí)之路的又一大模塊,即網(wǎng)關(guān)模塊。網(wǎng)關(guān)模塊我們廢棄了...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • Spring Cloud Gateway實(shí)戰(zhàn)之五:內(nèi)置filter

    摘要:歡迎訪(fǎng)問(wèn)我的歡迎訪(fǎng)問(wèn)我的內(nèi)容所有原創(chuàng)文章分類(lèi)匯總及配套源碼,涉及等本篇概覽本篇概覽作為實(shí)戰(zhàn)系列的第五篇,是時(shí)候了解過(guò)濾器的作用了,本篇咱們一起來(lái)了解內(nèi)置好的過(guò)濾器,真是種類(lèi)繁多功能強(qiáng)大過(guò)濾器顧名思義,就是在請(qǐng)求頭部添加指定的內(nèi)容帶有的完整配歡迎訪(fǎng)問(wèn)我的GitHubhttps://github.com/zq2599/blog_demos內(nèi)容:所有原創(chuàng)文章分類(lèi)匯總及配套源碼,涉及Java、Doc...

    reclay 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<