I am trying to use the WebClient
to call my restServices. Previously on RestTemplate
, we had ClientHttpRequestInterceptor
defined and
You can use an ExchangeFilterFunction
and configure it on the WebClient
instance you’re using. See the Spring Framework reference documentation for more on that.
In my case i need to get Some headers from incoming requests and put them into my requests. I find what i need here.
First of all a filter is needed
/**
* ReactiveRequestContextFilter
*
* @author L.cm
*/
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveRequestContextFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
return chain.filter(exchange)
.subscriberContext(ctx -> ctx.put(ReactiveRequestContextHolder.CONTEXT_KEY, request));
}
}
And ReactiveRequestContextHolder
/**
* ReactiveRequestContextHolder
*
* @author L.cm
*/
public class ReactiveRequestContextHolder {
static final Class<ServerHttpRequest> CONTEXT_KEY = ServerHttpRequest.class;
/**
* Gets the {@code Mono<ServerHttpRequest>} from Reactor {@link Context}
* @return the {@code Mono<ServerHttpRequest>}
*/
public static Mono<ServerHttpRequest> getRequest() {
return Mono.subscriberContext()
.map(ctx -> ctx.get(CONTEXT_KEY));
}
}
And finally like Michael McFadyen say you need to configure an ExchangeFilterFunction
, in my case i need Auth and origin:
private ExchangeFilterFunction headerFilter() {
return (request, next) -> ReactiveRequestContextHolder.getRequest()
.flatMap(r -> {
ClientRequest clientRequest = ClientRequest.from(request)
.headers(headers -> {
headers.set(HttpHeaders.ORIGIN, r.getHeaders().getFirst(HttpHeaders.ORIGIN));
headers.set(HttpHeaders.AUTHORIZATION, r.getHeaders().getFirst(HttpHeaders.AUTHORIZATION));
})
.build();
return next.exchange(clientRequest);
});
}
When you are using the WebClient Builder you can pass in implementations of the ExchangeFilterFunction
interface using the filter()
method. This is the equivalent of the ClientHttpRequestInterceptor
for `RestTemplate.
WebClient Builder Docs: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.Builder.html#filter-org.springframework.web.reactive.function.client.ExchangeFilterFunction-
ExchangeFilterFunction Docs: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/ExchangeFilterFunction.html
For example:
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8080|)
.filter(logFilter())
.build();
private ExchangeFilterFunction logFilter() {
return (clientRequest, next) -> {
logger.info("External Request to {}", clientRequest.url());
return next.exchange(clientRequest);
};
}