springCloud的feign异常:RequestHeader参数为空时,对key加了大括号{}

  好久没写博客了,今天趁着周末把工作中遇到的问题梳理一下(在这个问题排查过程中,发现自己排查问题的能力还是太弱了,需要加强)。

  最近在公司springCloud的项目里,通过feign远程调用其他服务,代码如下,可以看到,这里的RequestHeader里面我传了String类型的tenantId,测试的时候没有问题,但是项目上线后,发现部分用户在调用这个接口的时候返回的不是想要的结果,当然大部分用户使用的时候是正常的。然后我们就打印了日志,查看了调用链路,发现只要RequestHeader里面的tenantId为null的时候,就会出错,client传递的tenantId为null的时候,server收到的参数为“{tenantId}”,你没看错,就是在参数的key上面加了大括号。这个有点匪夷所思了。

/**
     * 查询用户动态提额(仅限卡面使用)
     * @param tenantId
     * @param paramJson
     * @return
     */
    @RequestMapping(value = "${wk.url.quota}/api/quota/findDynamicQuotaByCustomerId", method = RequestMethod.POST)
    String findDynamicQuotaByCustomerId(@RequestHeader String tenantId, @RequestBody JSONObject paramJson);

  通过排查,查资料,发现是由于feign底层的源码的问题,见下面红色字体部分。当时我们用的springCloud版本是Finchley.SR2。但是新版的springCloud里面已经修复了这个问题。

public static String expand(String template, Map<String, ?> variables) {
    // 如果没有设置有效变量,则跳过扩展。
    if (checkNotNull(template, "template").length() < 3) {
      return template;
    }
    checkNotNull(variables, "variables for %s", template);
    boolean inVar = false;
    StringBuilder var = new StringBuilder();
    StringBuilder builder = new StringBuilder();
    for (char c : template.toCharArray()) {
      switch (c) {
        case '{':
          if (inVar) {
            // '{{' 是转义字符,不进行解析
            builder.append("{");
            inVar = false;
            break;
          }
          inVar = true;
          break;
        case '}':
          if (!inVar) {
            builder.append('}');
            break;
          }
          inVar = false;
          String key = var.toString();
          //这里的variables就是header的map,由于header中的name值为null,所以这里只有一个key-value
          Object value = variables.get(var.toString());
          if (value != null) {
            builder.append(value);
          } else {
          //“罪魁祸首”就在这里,又把初始化时的默认值返回了
            builder.append('{').append(key).append('}');
          }
          var = new StringBuilder();
          break;
        default:
          if (inVar) {
            var.append(c);
          } else {
            builder.append(c);
          }
      }
    }
    return builder.toString();
  }

  所以解决办法很简单:1)升级springCloud版本;2)使出入的参数不能为null。

 

参考博客:https://www.jianshu.com/p/550fb3b5f533

猜你喜欢

转载自www.cnblogs.com/DDgougou/p/11964406.html