How to intercept a request when using SpringBoot WebClient

后端 未结 3 586
广开言路
广开言路 2020-12-18 10:26

I am trying to use the WebClient to call my restServices. Previously on RestTemplate, we had ClientHttpRequestInterceptor defined and

相关标签:
3条回答
  • 2020-12-18 11:10

    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.

    0 讨论(0)
  • 2020-12-18 11:21

    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);
                });
    }
    
    0 讨论(0)
  • 2020-12-18 11:27

    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);
        };
    }
    
    0 讨论(0)
提交回复
热议问题