gpt4 book ai didi

project-reactor - 将多个 REST 调用与 Spring Webflux 结合使用

转载 作者:行者123 更新时间:2023-12-04 18:57:45 25 4
gpt4 key购买 nike

我试图用 Spring Webflux 做一些事情,但我真的对一些 react 性概念感到困惑。

我有一些受表单例份验证保护的 REST 服务,在我可以调用我的业务 REST 服务之前,我必须调用通过 Spring Security 提供的“登录”URL,传递我的凭据并将返回的 Cookie 放置到对其他 REST 服务的进一步调用中.

下面是调用 REST 业务服务的代码段......

@RequestMapping(value = "/endpoint1", method = RequestMethod.POST)
public Mono<String> businessService(@RequestBody ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
log.info("Handling /enpoint1");

Mono<String> t = fetch(apiManagementWrapper, httpRequest);

return t;
}

private Mono<String> fetch(ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
return this.webClientProxy
.post()
.uri("http://localhost:8081/something")
.headers(httpHeaders -> httpRequest.getRequest().getHeaders())
.cookies(httpCookies -> httpRequest.getRequest().getCookies())
.body(BodyInserters.fromPublisher(Mono.just(apiManagementWrapper.getEnterpriseMessage()), Object.class))
.exchange()
.flatMap(response -> response.bodyToMono(String.class));
}

完美的我的问题是如何将其与调用登录服务结合起来。

我想过以下 login() 方法...
private void login(ApiManagementWrapper apiManagementWrapper) {
LinkedMultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("username", "user1");
formData.add("password", "user1");

Mono<ClientResponse> response = this.webClientRouteConfirmation
.post()
.uri("http://localhost:8383/login")
.body(BodyInserters.fromFormData(formData))
.exchange();

response.subscribe(clientResponse -> {
handleLogin(clientResponse.cookies().getFirst("JSESSION_ID"), apiManagementWrapper);
});
}

private void handleLogin(ResponseCookie loginCookie, ApiManagementWrapper apiManagementWrapper){
Mono<Route> route = loadRoute(apiManagementWrapper.getEnterptiseContext(), loginCookie);
if(route == null) {
return;
}
}


private Mono<Route> loadRoute(EnterpriseContext enterpriseContext, ResponseCookie loginCookie) {
Mono<Route> route = this.webClientRouteConfirmation
.get()
.uri("http://localhost:8383/routes/search/findByServiceIdAndClientId?serviceName=" + enterpriseContext.getTarget() + "&clientName" + enterpriseContext.getSource())
.cookie("JSESSION_ID", loginCookie.getValue())
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(Route.class));

route.subscribe(r -> {
handleRoute(enterpriseContext, loginCookie);
});
}

使用 'login()' 方法我可以获得 'JSESSION_ID' Cookie,但是当它返回 Mono 时我无法访问 Cookie 值(我可以使用 clientResponse.block() 但我知道它是邪恶的所以尽量不要这样做),所以我尝试通过回调订阅 clientResponse,但是如果我尝试这样做,我将与 'businessService()' 方法分离,并且将无法返回我喜欢的值...

所以我想要实现的伪代码如下......
@RequestMapping(value = "/endpoint1", method = RequestMethod.POST)
public Mono<String> businessService(@RequestBody ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
log.info("Handling /netty1");

Route route = login(apiManagementWrapper);

Mono<String> t = null;
if(route != null) {
t = fetch(apiManagementWrapper, httpRequest);
}

return t;
}

但我不知道如何在不使用 Mono.block() 的情况下去那里。

从 'handleLogin()' 返回 'Route' 对象没有任何意义,因为如果我正确理解 Reactive 概念,'fetch()' 方法无论如何都不会等待它......

有小费吗?

最佳答案

您可以在全局范围内应用的东西:

  • 让你的方法返回 react 类型,如 Mono<T>Flux<T>
  • 避免使用 subscribe在您的 Web 应用程序中,因为它将执行与当前请求/响应分离,并且不保证该任务的完成

  • 然后,您可以使用可用的运算符组合这些响应式(Reactive)类型。就像是:
    Mono<LoginInformation> login = doLogin();
    Mono<String> value = login.flatMap(info -> callRemoteService(info));

    关于project-reactor - 将多个 REST 调用与 Spring Webflux 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48064421/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com