Feign详解4-Encoder,Decoder组件源码分析

 在Feig.Builder类中装配的encoder与decoder分别用于编码与解码。

public abstract class Feign {
    ...
    public static class Builder {
        private Encoder encoder = new Encoder.Default();
        private Decoder decoder = new Decoder.Default();
        ...
    }
}

Encoder是一个接口,在这个接口中已经有一个Default的默认实现,这个接口中最重要的方法就是encode,以提供一个对内容的编码实现. 

public interface Encoder {
 
  Type MAP_STRING_WILDCARD = Util.MAP_STRING_WILDCARD;
  
  void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;

  class Default implements Encoder {

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) {
      if (bodyType == String.class) {
        template.body(object.toString());   //一个字符串的编码器
      } else if (bodyType == byte[].class) {
        template.body((byte[]) object, null);
      } else if (object != null) {
        throw new EncodeException(
            format("%s is not a type supported by this encoder.", object.getClass()));
      }
    }
  }
}

Decoder与Encoder正好是一个反向执行过程,它提供解码的实现.  它也提供一个默认实现,默认是一个字符串的解码器。 

public interface Decoder {

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

  //默认是一个字符串的解码器
  public class Default extends StringDecoder {

    @Override
    public Object decode(Response response, Type type) throws IOException {
      if (response.status() == 404 || response.status() == 204)
        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);
    }
  }
}

前面我们也讲过,我们可以给Feign加入其它的编码器,通过以下代码完成:  decoder(new GsonDecoder())

 GitHub2_javax github = Feign.builder()
                .decoder(new GsonDecoder())
                .options(  new Request.Options(1000,3500))  //options方法指定连接超时时长及响应超时时长
                .retryer(  new Retryer.Default(5000,5000,3))   // retryer方法主要是指定重试策略
                .contract(new JAXRSContract())   // Contract 指明是哪种注解规范
                .target(GitHub2_javax.class, "https://api.github.com");  // 为构造器配置本地的代理接口,和远程的根目录。代理接口类的每一个接口方法前@RequestLine 声明的值,最终都会加上这个根目录。

     

下面我们查看一下  GsonDecoder()的实现:

public class GsonDecoder implements Decoder {

  private final Gson gson;

  public GsonDecoder(Iterable<TypeAdapter<?>> adapters) {
    this(GsonFactory.create(adapters));
  }

  public GsonDecoder() {
    this(Collections.<TypeAdapter<?>>emptyList());
  }

  public GsonDecoder(Gson gson) {
    this.gson = gson;
  }

  @Override
  public Object decode(Response response, Type type) throws IOException {
    if (response.body() == null)
      return null;
    Reader reader = response.body().asReader();
    try {
      return gson.fromJson(reader, type);
    } catch (JsonIOException e) {
      if (e.getCause() != null && e.getCause() instanceof IOException) {
        throw IOException.class.cast(e.getCause());
      }
      throw e;
    } finally {
      ensureClosed(reader);
    }
  }
}

从这些代码中我们可知,GsonDecoder实现了Decoder接口,重写了decode()方法, 在这个方法中,它是调用了google的gson.fromJson()来完成json字符串转为对象的操作的. 

以上明白后,其它的Decoder和Encoder就可以自己去看源码学习了. 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangyingchengqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值