WebClient ExchangeFilterFunction 无法添加标头 java.lang.UnsupportedOperationException ReadOnlyHttpHeaders

use*_*841 3 spring-boot project-reactor spring-webflux

我正在尝试向 WebClient 请求添加一个简单的 ExchangeFilterFunction。但是,我看到以下异常:

java.lang.UnsupportedOperationException
    at org.springframework.http.ReadOnlyHttpHeaders.add(ReadOnlyHttpHeaders.java:84)
    at com.ecs.springframework.reactive.web.filter.AddHeaderExchangeFilter.filter(AddHeaderExchangeFilter.java:24)
    at org.springframework.web.reactive.function.client.ExchangeFilterFunction.lambda$apply$2(ExchangeFilterFunction.java:66)
    at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.exchange(DefaultWebClient.java:319)
    at com.ecs.springframework.reactive.web.filter.AddHeaderExchangeFilterTest.whenExchangeFilterFunctionInjectedIntoWebClient_thenWebClientShouldPropagate(AddHeaderExchangeFilterTest.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at 
Run Code Online (Sandbox Code Playgroud)

交换过滤功能

    public class AddHeaderExchangeFilter implements ExchangeFilterFunction {

      @Override
      public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {

        ClientRequest newRequest = ClientRequest.create(request.method(), request.url()).build();
        newRequest.headers().add("EFF-TEST-HEADER", "EFF-TEST-VALUE");
        return next.exchange(newRequest);
      }
    }
Run Code Online (Sandbox Code Playgroud)


        WebClient webTestClient = WebClient.builder().filter(new AddHeaderExchangeFilter()).build();

    webTestClient.get().uri("http://httpbin.org/get").exchange();
Run Code Online (Sandbox Code Playgroud)

我对 WebFlux 比较陌生,所以任何指点都将不胜感激。

Avi*_*evy 6

创建时需要添加标题newRequest

    public class AddHeaderExchangeFilter implements ExchangeFilterFunction {
        @Override
        public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {

            ClientRequest newRequest = ClientRequest.from(request)
                                                    .header("EFF-TEST-HEADER", "EFF-TEST-VALUE")
                                                    .build();
            return next.exchange(newRequest);
        }
    }
Run Code Online (Sandbox Code Playgroud)

您当前行为的原因是ClientRequest.create启动新的DefaultClientRequestBuilder. 您可以在Spring 的源代码
中看到,一旦您发出请求,构建器就会使用只读标头构建请求,因此在构建.build()ClientRequest