Spring Cloud Gateway 出现POST请求获取Body报错问题

1,385 阅读1分钟

报错信息:

java.lang.IllegalArgumentException: Unable to handle DataBuffer of type class org.springframework.http.server.reactive.UndertowServerHttpRequestUndertowDataBufferatorg.springframework.cloud.gateway.filter.NettyRoutingFilter.getByteBuf(NettyRoutingFilter.java:219)atreactor.core.publisher.FluxMapUndertowDataBuffer at org.springframework.cloud.gateway.filter.NettyRoutingFilter.getByteBuf(NettyRoutingFilter.java:219) at reactor.core.publisher.FluxMapMapSubscriber.onNext(FluxMap.java:100) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.readAndPublish(AbstractListenerReadPublisher.java:196) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access1100(AbstractListenerReadPublisher.java:48)atorg.springframework.http.server.reactive.AbstractListenerReadPublisher1100(AbstractListenerReadPublisher.java:48) at org.springframework.http.server.reactive.AbstractListenerReadPublisherState4.onDataAvailable(AbstractListenerReadPublisher.java:374)atorg.springframework.http.server.reactive.AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:118)atorg.springframework.http.server.reactive.UndertowServerHttpRequest4.onDataAvailable(AbstractListenerReadPublisher.java:374) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:118) at org.springframework.http.server.reactive.UndertowServerHttpRequestRequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:168) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:222) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.access1000(AbstractListenerReadPublisher.java:48)atorg.springframework.http.server.reactive.AbstractListenerReadPublisher1000(AbstractListenerReadPublisher.java:48) at org.springframework.http.server.reactive.AbstractListenerReadPublisherState2.request(AbstractListenerReadPublisher.java:333)atorg.springframework.http.server.reactive.AbstractListenerReadPublisher2.request(AbstractListenerReadPublisher.java:333) at org.springframework.http.server.reactive.AbstractListenerReadPublisherReadSubscription.request(AbstractListenerReadPublisher.java:260) at reactor.core.publisher.FluxMapMapSubscriber.request(FluxMap.java:155)atreactor.netty.channel.MonoSendManyMapSubscriber.request(FluxMap.java:155) at reactor.netty.channel.MonoSendManySendManyInner.onSubscribe(MonoSendMany.java:250) at reactor.core.publisher.FluxMapMapSubscriber.onSubscribe(FluxMap.java:86)atorg.springframework.http.server.reactive.AbstractListenerReadPublisherMapSubscriber.onSubscribe(FluxMap.java:86) at org.springframework.http.server.reactive.AbstractListenerReadPublisherState1.subscribe(AbstractListenerReadPublisher.java:301)atorg.springframework.http.server.reactive.AbstractListenerReadPublisher.subscribe(AbstractListenerReadPublisher.java:105)atreactor.core.publisher.FluxSource.subscribe(FluxSource.java:65)atreactor.core.publisher.Flux.subscribe(Flux.java:8358)atreactor.netty.channel.MonoSendMany.subscribe(MonoSendMany.java:102)atreactor.core.publisher.MonoIgnoreThen1.subscribe(AbstractListenerReadPublisher.java:301) at org.springframework.http.server.reactive.AbstractListenerReadPublisher.subscribe(AbstractListenerReadPublisher.java:105) at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:65) at reactor.core.publisher.Flux.subscribe(Flux.java:8358) at reactor.netty.channel.MonoSendMany.subscribe(MonoSendMany.java:102) at reactor.core.publisher.MonoIgnoreThenThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:234) at reactor.core.publisher.MonoIgnoreThenThenIgnoreMain.onComplete(MonoIgnoreThen.java:201)atreactor.core.publisher.Operators.complete(Operators.java:135)atreactor.netty.FutureMonoThenIgnoreMain.onComplete(MonoIgnoreThen.java:201) at reactor.core.publisher.Operators.complete(Operators.java:135) at reactor.netty.FutureMonoDeferredFutureMono.subscribe(FutureMono.java:130) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:253) at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at reactor.netty.NettyOutbound.subscribe(NettyOutbound.java:336) at reactor.core.publisher.MonoSource.subscribe(MonoSource.java:65) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)

排查现场:

目前Spring Gateway的版本2.2.8版本,Spring Cloud 使用Hoxton.SR11版本

查了些资料都说是,新版的Gateway都存在【post/put请求获取不到Body的问题】

但是get/delete是正常

采用大牛的解决方案:blog.csdn.net/qq_38225558… 也能解决这个问题

但是我认为这个不是最根本的解决方案,而且这样处理后我在后期出现了一些新的其他问题

后来通过分析,Unable to handle DataBuffer of type class org.springframework.http.server.reactive.UndertowServerHttpRequest$UndertowDataBuffer

会不会是WEB容器Undertow自身的问题,其他容器有可能没得这个问题呢?

初步解决方案:

将Undertow容器修改为Tomcat容器

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    

然后尝试下,发现问题消失的无影无踪了

总结:

Spring新版本的啊,总是伴随着这种或那种问题,特别磨人,在项目中谨慎升级最新版本