Spring Cloud OpenFeign的若干问题与近期更新

一个rpc在2019年才解决url encode、参数继承、request model等问题。

Feign与OpenFeign

Feign是Netflix开源的一个声明式HTTP客户端,9.0起迁移至OpenFeign,简要的历史可见 Move to a new org

Spring Cloud中和Feign相关的代码原在Spring Cloud Netflix项目内。在Finchley.M7(Spring Cloud Netflix 2.0.0.M7)版本中,Feign相关的代码迁移到一个新项目Spring Cloud OpenFeign内。即org.springframework.cloud.netflix.feign相关代码改为org.springframework.cloud.openfeign

然而作为一个声明式客户端,Feign居然在近期的几个版本才解决一些基础性问题(model传参、丢model父类参数、url encode等等),很容易踩坑。我在项目中遇到过的问题如下:

  1. Spring Cloud OpenFeign自Greenwich起支持query map声明为model。
  2. Feign 10.2.0(Spring Cloud Greenwich.SR2)修复+号在query string中未encode问题。
  3. Feign 10.3.0(Spring Cloud Greenwich.SR4)支持model继承。
  4. Spring Cloud Alibaba 2.1.0.RELEASE修复Feign接口继承时产生的空指针。

Spring OpenFeign的若干问题

Model作为Query Map的支持

Feign支持Model转换为QueryMap(9.7.0之后可以设置encode: https://github.com/OpenFeign/feign/pull/667 ),但是Feign的@QueryMap注解由于缺少value字段,在Spring Cloud OpenFeign中并不支持。

Spring Cloud OpenFeign的2.1.x版本中增加@SpringQueryMap注解,从此支持将Model转换为QueryMap,但是如果Model中有serialVersionUID字段,也会被放入请求参数中。

Feign对Query String特殊字符的encode

Feign 10.x引入一个新问题:对query string未将+号转换为%2B,在10.2.0版本中修复(Adding URI segment specific encoding)。

Spring Cloud OpenFeign 2.1.2版本升级到Feign 10.2.3,修复该问题。

Feign使用model时无法生成父类的字段参数

虽然有了@SpringQueryMap,但如果使用了含有继承关系的model,如XXXReq extends BaseReq,Feign只能将XXXReq中参数放在url中,BaseReq中的内容丢失。在Feign 10.3.0中解决,PR见This pr resolves QueryMap inheritance issue #927

Spring Cloud OpenFeign 2.1.4版本升级到Feign 10.4.0,修复该问题。

在继承Feign接口时使用Sentinel出现空指针

Spring Cloud Alibaba的一个问题,详情见 Feign with Sentinel in Inheritance interface will throw NPE,在新版本中修复了这个问题。

Spring Cloud发布列车和OpenFeign及Feign的版本关系:

Spring Cloud版本 OpenFeign版本 Feign版本
Greenwich.RELEASE 2.1.0.RELEASE 9.5.1
Greenwich.SR1 2.1.1.RELEASE 9.5.1
Greenwich.SR2 2.1.2.RELEASE 10.2.3
Greenwich.SR3 2.1.3.RELEASE 10.2.3
Greenwich.SR4 2.1.4.RELEASE 10.4.0

总结:使用Spring Cloud Greenwich.SR4可以避免上面各已知问题,Spring Cloud Alibaba的问题也在最新版(2.1.0.RELEASE)解决。