【Feign源码】保存请求数据的载体--Template

本文详细介绍了Feign中Template的实现原理,从父类Template开始,探讨了替换占位符、UriTemplate、HeaderTemplate、QueryTemplate和BodyTemplate的逻辑。Template用于保存请求的各个部分,并在请求时替换占位符。解析过程包括将原始字符串解析为普通字符串和Expression,然后在实际请求时进行替换。UriTemplate、HeaderTemplate、QueryTemplate和BodyTemplate各有特点,例如HeaderTemplate处理请求头,QueryTemplate处理查询参数,而BodyTemplate则用于处理请求体。
摘要由CSDN通过智能技术生成

请求数据的保存是使用Template实现的。如下图所示,每个请求的部分都是一个Template。
在这里插入图片描述

父类Template

属性

  // 用来区分查询参数的正则
  private static final Pattern QUERY_STRING_PATTERN = Pattern.compile("(?<!\\{)(\\?)");
  // 原始字符串
  private final String template;
  // 允许不解析,当没有合适的值时,可以不解析
  private final boolean allowUnresolved;
  // 编码
  private final EncodingOptions encode;
  // 是否编码斜杠  / 
  private final boolean encodeSlash;
  private final Charset charset;
  // 占位符将原始字符串分开,每个是一个TemplateChunk
  // /provider/userinfo/{id}/test/{age} list包含了这四个分 {} 这种类型是需要解析的,替换为真正的值
  // /provider/userinfo/ 
  // {id}
  // /test/
  // {age}      
  private final List<TemplateChunk> templateChunks = new ArrayList<>();

构造函数
分别给属性赋值,有一步逻辑操作时解析模板,就是将原始字符串解析,之后给templateChunks 赋值。

  Template(
      String value, ExpansionOptions allowUnresolved, EncodingOptions encode, boolean encodeSlash,
      Charset charset) {
   
    if (value == null) {
   
      throw new IllegalArgumentException("template is required.");
    }
    this.template = value;
    this.allowUnresolved = ExpansionOptions.ALLOW_UNRESOLVED == allowUnresolved;
    this.encode = encode;
    this.encodeSlash = encodeSlash;
    this.charset = charset;
    this.parseTemplate();
  }

可以看到解析的时候,{}这种占位符的解析成了Expression ,普通字符串只是Literal类型,只是保存字符串的对象。

 private void parseFragment(String fragment, boolean query) {
   
    ChunkTokenizer tokenizer = new ChunkTokenizer(fragment);

    while (tokenizer.hasNext()) {
   
      /* check to see if we have an expression or a literal */
      String chunk = tokenizer.next();

      if (chunk.startsWith("{")) {
   
        /* it's an expression, defer encoding until resolution */
        FragmentType type = (query) ? FragmentType.QUERY : FragmentType.PATH_SEGMENT;

        Expression expression = Expressions.create(chunk, type);
        if (expression == null) {
   
          this.templateChunks.add(Literal.create(encode(chunk, query)));
        } else {
   
          this.templateChunks.add(expression);
        }
      } else {
   
        /* it's a literal, pct-encode it */
        this.templateChunks.add(Literal.create(encode(chunk, query)));
      }
    }
  }

创建占位表达式

public static Expression create(final String value, final FragmentType type) {
   

    // 得到严格的表达式{id}->返回值是id,相当于取{}中间的字符串
    final String expression = stripBraces(value);
    if (expression == null || expression.isEmpty()) {
   
      throw new IllegalArgumentException("an expression is required.");
    }

    Optional<Entry<Pattern, Class<? extends Expression>>> matchedExpressionEntry =
        expressions.entrySet
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值