zoukankan      html  css  js  c++  java
  • 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

    在全栈的道路上,积极向上、成熟稳重、谦虚好学、怀着炽热的心向前方的走得更远。
  • 相关阅读:
    如何用RadioButton做一个底部的切换栏
    自定义有监听器的ScrollView
    ViewPager的使用小技巧
    什么时候用Application的Context,什么时候用Activity的Context
    让改变输入法回车键的图标
    墙内下载DropBox离线安装包的方法
    巧用用layer-list做一个卡片背景
    LeakCanary中英文文档+使用例子
    让你的APK瘦成一道闪电
    用一张图片实现按钮按下和普通效果的样式
  • 原文地址:https://www.cnblogs.com/DDgougou/p/11964406.html
Copyright © 2011-2022 走看看