2 回答

TA貢獻1815條經驗 獲得超6個贊
我解決了這個問題。在調用 auth api 之前,我暫停原始請求,并在授權完成后恢復緩沖區處理。
router.route().path("/user/admin").method(HttpMethod.POST)
.handler(rct -> {
HttpServerRequest request = rct.request().setExpectMultipart(true);
request.pause(); // Here is to pasue the origin request.
MultiMap headers = request.headers();
JsonObject param = new JsonObject().put("requestUrl", "http://localhost:18080/authorize")
.put("httpMethod", "POST");
webClient.postAbs("http://localhost:18080/authorize")
.timeout(6000)
.putHeader("Content-Type", "application/json")
.putHeader("Authorization", headers.get("Authorization"))
.as(BodyCodec.jsonObject())
.sendJsonObject(param, ar -> authHandler(rct, ar));
});

TA貢獻1810條經驗 獲得超4個贊
您可能最終會遇到此錯誤的兩個原因:
A) 異步Handler
之前BodyHandler
正如 Vert.X文檔中所述BodyHandler
:
使用此處理程序需要盡快將其安裝在路由器中,因為它需要安裝處理程序來使用 HTTP 請求正文,并且必須在執行任何異步調用之前完成此操作。
修復1:更改順序:
router.post(endpoint) ???.consumes(contentType) ???.handler(bodyHandler)??<<<<<<<<<?first?this ???.handler(authHandler)?<<<<<<<<??then?this?async?handler;
修復 2:暫停/恢復請求傳送:
請參閱 Vert.X文檔:
如果之前需要異步調用,則應暫停 HttpServerRequest?,然后再恢復,以便在主體處理程序準備好處理請求事件之前不會傳遞請求事件。
router.post(endpoint) ???.consumes(contentType) ???.handler(authHandler) ???.handler(bodyHandler);
BodyHandler implements Handler<RoutingContext> {
? @Override
? public void handle(final RoutingContext ctx) {
? ? ?// pause request delivery
? ? ?ctx.request().pause();
? ? ?asyncCall(r -> {
? ? ? ? // e.g. check authorization or database here
? ? ? ? // resume request delivery
? ? ? ? ctx.request.resume();
? ? ? ? // call the next handler
? ? ? ? ctx.next();
? ? ?}
? }
}
B) 多次request.body()
調用
假設您使用 Vert.XBodyHandler
并在其后安裝了自定義處理程序:
router.post(endpoint) ???.consumes(contentType) ???.handler(BodyHandler.create()) ???.handler(customHandler);
您的自定義處理程序不得調用request.body()
!否則你會得到
403:?body?has?already?been?read
修復:使用ctx.getBody()
用于ctx.getBody[/asJson/asString]()
獲取已被讀取的正文BodyHandler
:
CustomHandler implements Handler<RoutingContext> {
? ? @Override
? ? public void handleAuthorizedRequest(RoutingContext ctx) {
? ? ? ? final var body = ctx.getBodyAsJson();
? ? ? ? // instead of: ctx.request().body();
? ? ? ? ...
? ? }
}
添加回答
舉報