文章
问答
冒泡
feign client中对不同类型返回值decode的处理

在spring cloud的微服务项目中,我们在微服务之间的调用经常是通过feign client去操作的。

由于是局域http的rest风格接口,很多人会去做一层包装,类似这种:

{
"code":"ok",
"message":null,
"data":"hello"
}

如果是这种对象形式的返回值,一般是没有问题的。但是,由于是微服务,有的时候,我们会更倾向于贴近RPC的写法,返回什么,就是什么,不做包装。这样一来,我们就可以返回String,Integer,Long,Object等各种类型的返回值。

之前我是用的JacksonDecode作为decode的实现方式,在一次使用String 作为返回类型的时候,发现会报错。原因就是jackson不能直接继续一个非json的字符串。于是,便考虑其他途径。

我们先看Decode的接口

public interface Decoder {

  Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;

  /** Default implementation of {@code Decoder}. */
  public class Default extends StringDecoder {

    @Override
    public Object decode(Response response, Type type) throws IOException {
      if (response.status() == 404)
        return Util.emptyValueOf(type);
      if (response.body() == null)
        return null;
      if (byte[].class.equals(type)) {
        return Util.toByteArray(response.body().asInputStream());
      }
      return super.decode(response, type);
    }
  }
}

由代码可见,主要就是调用decode方法,参数是返回对象,以及目标类型。默认的实现类中,主要是针对byte[]类型的进行处理的。那么我们应该考虑其他实现类。

除去JacksonDecode,还有其他实现类可选。比较下实现源码springDecode是做了适配的。所以选择SpringDecode作为Decode的实现类。

@Bean
public Decoder decoder(){
    MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(new ObjectMapper());
    ObjectFactory<HttpMessageConverters> objectFactory = ()->(new HttpMessageConverters(jacksonConverter));
    return new SpringDecoder(objectFactory);
}

通过对SpringDecode的源码阅读会发现,这里的实现很多是基于Spring的,如果非spring框架的项目,可以考虑自己写一个实现类,其实也很方便的。只要写一个decode实现方法,里面根据Type类型去做对应处理即可。


关于作者

落雁沙
非典型码农
获得点赞
文章被阅读