[英]How to use Spring WebClient to make a subsequent call with different header setting?
我需要調用第三方 API,該 API 需要事先進行身份驗證調用才能獲取身份驗證令牌。 身份驗證 API 在 json 中,但后續調用在 XML 中。
我分別有:
webclient.post().uri("/auth").header(ACCEPT,JSON).retrieve()
.bodyToMono(AuthToken.class);
webclient.post().uri("/api").header(ACCEPT,XML).header("AUTH",authToken).retrive().bodyToFlux();
我應該如何實現能夠訪問第二個 API 的方法? 我試圖用token = firstCall.block()
在方法內分配一個變量,但我有block() is not supported
錯誤。
你只需要像這樣轉換原始通量:
webclient.post().uri("/auth")
.header(ACCEPT,JSON)
.retrieve()
.bodyToMono(AuthToken.class)
.flatMapMany(authToken -> webclient.post().uri("/api")
.header(ACCEPT,XML)
.header("AUTH",authToken).retrive().bodyToFlux();
更好的解決方案是使用 ExchangeFilterFunction 為您獲取令牌https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web-reactive.html#webflux-client-篩選
類似的東西(未測試可能有錯誤):
WebClient authWebClient = WebClient.builder().build();
WebClient webClient = WebClient.builder()
.filter(((request, next) -> authWebClient.post()
.uri("/auth")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(AuthToken.class)
.flatMap(authToken -> next.exchange(ClientRequest.from(request)
.headers(headers -> headers.add("AUTH", authToken))
.build()))
))
.build();
webClient.post().uri("/api")
.accept(MediaType.APPLICATION_XML)
.retrieve()
.bodyToFlux(MyData.class);
這是基本的,但您可以添加緩存以避免在令牌過期時再次請求或獲取...請注意,基本的 oauth2 存在內置 ExchangeFilterFunction ...
用彈簧配置包裹一切:
@Configuration
public class WebClientConfiguration {
@Bean
public WebClient authWebClient(final WebClient.Builder webClientBuilder) {
return webClientBuilder.build();
}
@Bean
public ExchangeFilterFunction authFilter(final WebClient authWebClient) {
return (request, next) -> authWebClient.post()
.uri("/auth")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(AuthToken.class)
.flatMap(authToken -> next.exchange(ClientRequest.from(request)
.headers(headers -> headers.add("AUTH", authToken.toString()))
.build()));
}
@Bean
public WebClient webClient(final WebClient.Builder webClientBuilder, final ExchangeFilterFunction authFilter) {
return webClientBuilder
.filter(authFilter)
.build();
}
}
或者,如果您想避免使用 lambda:
@Configuration
public class WebClientConfiguration {
@Bean
public WebClient authWebClient(final WebClient.Builder webClientBuilder) {
return webClientBuilder.build();
}
@Bean
public WebClient webClient(final WebClient.Builder webClientBuilder, final AuthFilter authFilter) {
return webClientBuilder
.filter(authFilter)
.build();
}
@Bean
public AuthFilter authFilter(WebClient authWebClient) {
return new AuthFilter(authWebClient);
}
}
public class AuthFilter implements ExchangeFilterFunction {
private final WebClient authWebClient;
public AuthFilter(WebClient authWebClient) {
this.authWebClient = authWebClient;
}
@Override
public Mono<ClientResponse> filter(final ClientRequest request, final ExchangeFunction next) {
return authWebClient.post()
.uri("/auth")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(AuthToken.class)
.flatMap(authToken -> next.exchange(ClientRequest.from(request)
.headers(headers -> headers.add("AUTH", authToken.toString()))
.build()));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.