FeignClient动态参数之坑--

动态参数配置

@PostMapping(value = "{reqPath}")
Result<DemoResp> orderPushCommon(URI uri, @PathVariable("reqPath")String reqPath,@RequestBody DemoBody param);

配置的URI:  https://demo.xx.com

配置的reqPath:   /api/demo/test

在实际调用时生成的URL为:https://demo.xx.com//api/demo/test,即路径多了个斜杠/。

初步解决方案:

1、https://demo.xx.com改为https://demo.xx.com/

2、或者 /api/demo/test 改为 api/demo/test

此两种方式选其一即可

feign.Contract.BaseContract#parseAndValidateMetadata

protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
      MethodMetadata data = new MethodMetadata();
      data.returnType(Types.resolve(targetType, targetType, method.getGenericReturnType()));
      data.configKey(Feign.configKey(targetType, method));

      if(targetType.getInterfaces().length == 1) {
        processAnnotationOnClass(data, targetType.getInterfaces()[0]);
      }
      processAnnotationOnClass(data, targetType);


      for (Annotation methodAnnotation : method.getAnnotations()) {
        processAnnotationOnMethod(data, methodAnnotation, method);
      }
      checkState(data.template().method() != null,
                 "Method %s not annotated with HTTP method type (ex. GET, POST)",
                 method.getName());
      Class<?>[] parameterTypes = method.getParameterTypes();
      Type[] genericParameterTypes = method.getGenericParameterTypes();

      Annotation[][] parameterAnnotations = method.getParameterAnnotations();
      int count = parameterAnnotations.length;
      for (int i = 0; i < count; i++) {
        boolean isHttpAnnotation = false;
        if (parameterAnnotations[i] != null) {
          isHttpAnnotation = processAnnotationsOnParameter(data, parameterAnnotations[i], i);
        }
        if (parameterTypes[i] == URI.class) {
          data.urlIndex(i);
        } else if (!isHttpAnnotation) {
          checkState(data.formParams().isEmpty(),
                     "Body parameters cannot be used with form parameters.");
          checkState(data.bodyIndex() == null, "Method has too many Body parameters: %s", method);
          data.bodyIndex(i);
          data.bodyType(Types.resolve(targetType, targetType, genericParameterTypes[i]));
        }
      }

      if (data.headerMapIndex() != null) {
        checkMapString("HeaderMap", parameterTypes[data.headerMapIndex()], genericParameterTypes[data.headerMapIndex()]);
      }

      if (data.queryMapIndex() != null) {
        checkMapString("QueryMap", parameterTypes[data.queryMapIndex()], genericParameterTypes[data.queryMapIndex()]);
      }

      return data;
    }

注解在classs上的处理

org.springframework.cloud.netflix.feign.support.SpringMvcContract#processAnnotationOnClass

protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
        if (clz.getInterfaces().length == 0) {
            RequestMapping classAnnotation = (RequestMapping)AnnotatedElementUtils.findMergedAnnotation(clz, RequestMapping.class);
            if (classAnnotation != null && classAnnotation.value().length > 0) {
                String pathValue = Util.emptyToNull(classAnnotation.value()[0]);
                pathValue = this.resolve(pathValue);
                if (!pathValue.startsWith("/")) {
                    pathValue = "/" + pathValue;
                }

                data.template().insert(0, pathValue);
            }
        }

    }

注解在method的处理

org.springframework.cloud.netflix.feign.support.SpringMvcContract#processAnnotationOnMethod

protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
        if (RequestMapping.class.isInstance(methodAnnotation) || methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) {
            RequestMapping methodMapping = (RequestMapping)AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
            RequestMethod[] methods = methodMapping.method();
            if (methods.length == 0) {
                methods = new RequestMethod[]{RequestMethod.GET};
            }

            this.checkOne(method, methods, "method");
            data.template().method(methods[0].name());
            this.checkAtMostOne(method, methodMapping.value(), "value");
            if (methodMapping.value().length > 0) {
                String pathValue = Util.emptyToNull(methodMapping.value()[0]);
                if (pathValue != null) {
                    pathValue = this.resolve(pathValue);
                    if (!pathValue.startsWith("/") && !data.template().toString().endsWith("/")) {
                        pathValue = "/" + pathValue;
                    }

                    data.template().append(pathValue);
                }
            }

            this.parseProduces(data, method, methodMapping);
            this.parseConsumes(data, method, methodMapping);
            this.parseHeaders(data, method, methodMapping);
            data.indexToExpander(new LinkedHashMap());
        }
    }

关键实现链路,后面在具体分析

1、创建实例
ReflectiveFeign extends Feign#feign.ReflectiveFeign#newInstance  
Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);

2、

feign.ReflectiveFeign.ParseHandlersByName#apply

List<MethodMetadata> metadata = contract.parseAndValidatateMetadata(key.type());
MethodMetadata metadata = parseAndValidateMetadata(targetType, method);

3、

feign.Contract.BaseContract#parseAndValidateMetadata


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值