摘要:一開(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 Monofilter(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 extends DataBuffer> body) { if (body instanceof Flux) { Flux extends DataBuffer> fluxBody = (Flux extends DataBuffer>) 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
摘要:歡迎訪(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...
摘要:公司要做自己的網(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)...
摘要:將請(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)模塊我們廢棄了...
摘要:歡迎訪(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...
閱讀 550·2021-11-25 09:44
閱讀 2636·2021-11-24 09:39
閱讀 2305·2021-11-22 15:29
閱讀 3520·2021-11-15 11:37
閱讀 3379·2021-09-24 10:36
閱讀 2507·2021-09-04 16:41
閱讀 992·2021-09-03 10:28
閱讀 1833·2019-08-30 15:55