Как решить java.lang.IllegalStateException: разрешено только одно подключение для получения подписчика

Я использовал spring-cloud-gateway для создания службы шлюза, но когда служба получает запрос POST, возникает это исключение: «java.lang.IllegalStateException: только одно соединение получает разрешенный подписчик». Как это решить? Ниже мой код. Спасибо.

@Override
public GatewayFilter apply(Object config) {
    return ((exchange, chain) -> {
        URI uri = exchange.getRequest().getURI();
        URI ex = UriComponentsBuilder.fromUri(uri).build(true).toUri();
        ServerHttpRequest request = exchange.getRequest().mutate().uri(ex).build();
        if ("POST".equalsIgnoreCase(request.getMethodValue())) {
            Flux<DataBuffer> body = request.getBody();
            AtomicReference<String> bodyRef = new AtomicReference<>(); //used for cache request body

            //Cache request
            body.subscribe(dataBuffer -> {
                CharBuffer charBuffer = StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer());
                DataBufferUtils.release(dataBuffer);
                bodyRef.set(charBuffer.toString());
            });

            //generate bodyFlux
            String bodyStr = bodyRef.get();
            System.out.println(bodyStr);
            DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
            Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);

            // generate request by bodyFlux
            request = new ServerHttpRequestDecorator(request) {
                @Override
                public Flux<DataBuffer> getBody() {
                    return bodyFlux;
                }
            };
        }
        return chain.filter(exchange.mutate().request(request).build());
    });
}

// Generated DataBuffer from String
protected DataBuffer stringBuffer(String value) {
    byte[] bytes = value.getBytes(StandardCharsets.UTF_8);

    NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
    DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
    buffer.write(bytes);
    return buffer;
}

person Xin Guo    schedule 28.09.2018    source источник
comment
Это выглядит как github.com/spring-cloud/spring-cloud-gateway /вопросы/541   -  person Brian Clozel    schedule 01.10.2018
comment
Спасибо, я успешно решил эту проблему в соответствии с вашим руководством.   -  person Xin Guo    schedule 08.10.2018


Ответы (1)


Это похоже на следующую проблему: https://github.com/spring-cloud/spring-cloud-gateway/issues/541

В качестве временного обходного пути вы можете определить этот bean-компонент в своем приложении:

@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
    return new HiddenHttpMethodFilter() {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            return chain.filter(exchange);
        }
    };
}

Это исправлено начиная с "Гринвич.М1".

person Brian Clozel    schedule 09.10.2018