91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringCloud Gateway獲取post請求體(request body)

發布時間:2020-08-09 08:47:52 來源:網絡 閱讀:19871 作者:HappyBoyLi 欄目:建站服務器

獲取spring cloud gateway POST請求體的時候,會有很多坑,網上大多數解決方案是

/**
這種方法在spring-boot-starter-parent 2.0.6.RELEASE + Spring Cloud Finchley.SR2 body 中生效, 
但是在spring-boot-starter-parent 2.1.0.RELEASE + Spring Cloud Greenwich.M3 body 中不生效,總是為空
*/
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
        Flux<DataBuffer> body = serverHttpRequest.getBody();
        AtomicReference<String> bodyRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
            DataBufferUtils.release(buffer);
            bodyRef.set(charBuffer.toString());
        });
        return bodyRef.get();
    }

但是實際這種解決方案(例如 這篇文章)會帶來很多問題,比如request不能在其他filter中獲取,會報錯:

reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: Only one connection receive subscriber allowed.
Caused by: java.lang.IllegalStateException: Only one connection receive subscriber allowed.

針對這種不能重復獲取的問題,網上通用解決是把request重新包裝,繼續傳遞,比如 這篇文章的解決方案。
但是這種方案還會帶來request body獲取不完整,只能獲取1024B的數據,這個問題暫時沒有很好的解法,很頭痛,在給官方提issues的時候,issues709 和issues707 的時候,對方讓我參看一個類ModifyRequestBodyGatewayFilterFactory.java,說真的并沒有看懂,最后翻源碼的時候,發現了一個預言類,ReadBodyPredicateFactory ,發現里面緩存了request body的信息,于是在自定義router中配置了ReadBodyPredicateFactory,然后在filter中通過cachedRequestBodyObject緩存字段獲取request body信息,這種解決,一不會帶來重復讀取問題,二不會帶來requestbody取不全問題。三在低版本的Spring Cloud Finchley.SR2也可以運行。

step 1:現在自動以router里面配置ReadBodyPredicate預言類:
RouteLocatorBuilder.Builder serviceProvider = builder.
                routes().route("gateway-sample",
                    r -> r.readBody(Object.class, requestBody -> {
                        log.info("requestBody is {}", requestBody);
                        // 這里不對body做判斷處理
                        return true;
                }).and().path("/service").
                        filters(f -> {
                            f.filter(requestFilter);
                            return f;
                        })
                        .uri("http://127.0.0.1:8009"));
        RouteLocator routeLocator = serviceProvider.build();

step2:在自定義filter中獲取緩存了的request body:
      Object requestBody = exchange.getAttribute("cachedRequestBodyObject");

至此問題解決,完整代碼在我的github上面。參考這里。

參考:
https://www.cnblogs.com/cafebabe-yun/p/9328554.html
https://blog.csdn.net/tianyaleixiaowu/article/details/83375246

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大理市| 安仁县| 福鼎市| 邢台县| 新田县| 如皋市| 馆陶县| 新绛县| 达拉特旗| 西丰县| 新晃| 连平县| 黔西| 柳江县| 城市| 麻城市| 疏附县| 望城县| 翁源县| 河池市| 马关县| 两当县| 巴林右旗| 宜都市| 乃东县| 西青区| 大石桥市| 泰安市| 奉化市| 灌云县| 开原市| 额尔古纳市| 弋阳县| 常熟市| 大化| 田阳县| 章丘市| 崇礼县| 平塘县| 仁化县| 福海县|