http delete method请求经过zuul网关requestbody为空问题处理

最近我们在做微服务网关升级,因为我们的架构体系采用的Spring Boot+Spring Cloud,所以网关这块就直接采用Netflix的Zuul。做完网关升级后,测试同学在做系统回归测试,发现在调用一个http接口使用restful的delete method并带有request body的请求时,我们的业务微服务应用报错了:

org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

看到这个报错,第一反应是自己本地启动业务微服务测试,发现一切安好。考虑到测试环境的请求是先经过Zuul网关,网关再将请求转发到微服务,所以问题应该出现网关层。于是本地启动网关,让请求先经过本地的网关再到本地微服务,发现bug复现了。bug复现了就好办了,接下来调试网关的源码,在spring-cloud-netflix-core-1.4.4.RELEASE.jar包下面的RibbonRoutingFilter类中找到一段代码如下

其中的RibbonCommand有一个抽象实现类AbstractRibbonCommand,它又有三个子类:HttpClientRibbonCommand、OkHttpRibbonCommand、RestClientRibbonCommand。我们系统在application.properties里配置的httpclient如下:

ribbon.restclient.enabled=true

所以RibbonCommand此时使用的实现类是RestClientRibbonCommand,查看了源码:

上图中红色框部分,如果请求的Method是Delete,就将requestEntity设置为null,所以这就是为什么我们的业务微服务在网关转发了请求后得不到requestbody的原因。

那么为什么这个RestClientRibbonCommand类会把requestEntity设置为null呢?业界在Restful服务中Delete请求能否使用Entity body也是众说纷纭,有些http client支持有些又不支持,既然我们用的RestClientRibbonCommand不支持那么我们就换成OkHttpRibbonCommand或者HttpClientRibbonCommand呗。

于是我们最终在application.properties里将配置的httpclient改成:

# ribbon.restclient.enabled=true
ribbon.okhttp.enabled = true

重启服务,测试,解决问题。

 

Tonitech版权所有 | 转载请注明出处: http://www.tonitech.com/2528.html

发表评论