在Feign RequestInterceptor / RequestTemplate中访问URITemplate或RequestLine值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Feign RequestInterceptor / RequestTemplate中访问URITemplate或RequestLine值相关的知识,希望对你有一定的参考价值。

我正在针对具有硬api速率限制的云应用程序开发应用程序。为了让我的团队了解我们与这些限制有多接近,我想以有意义的方式计算从我们的应用程序发出的所有API调用。

我们使用Feign作为访问层,我希望能够使用RequestInterceptor来计算我们调用的不同API端点:

RequestInterceptor ri = rq -> addStatistics(rq.url());

现在这不起作用,因为结果URL之后几乎总是计为“1”,因为它们已经包含所有已解析的路径变量,所以我得到了计数

1 - /something/id1valueverycryptic/get
1 - /something/anothercrypticidkey/get

等等。

我希望以某种方式访问​​@ResuqestLine映射值(GET /something/{id}/get)或至少uri模板预解析(/somethine/{id}/get

有没有办法做到这一点?

谢谢!

答案

也许你可以尝试使用自定义假装InvocationHandlerFactory。

我设法使用这样的代码记录RequestInterceptor:

  • 更改EnableFeignClients并添加defaultConfiguration @EnableFeignClients(defaultConfiguration = FeignConfig.class)
  • 添加默认的feign配置 @Configuration public class FeignConfig { @Bean @ConditionalOnMissingBean public Retryer feignRetryer() { return Retryer.NEVER_RETRY; } @Bean @Scope("prototype") @ConditionalOnMissingBean public Feign.Builder feignBuilder(Retryer retryer) { return Feign.builder() .retryer(retryer) .invocationHandlerFactory((target, dispatch) -> new CountingFeignInvocationHandler(target, dispatch)); } }
  • 创建您的调用处理程序(基于feign.ReflectiveFeign.FeignInvocationHandler的代码) public class CountingFeignInvocationHandler implements InvocationHandler { private final Target target; private final Map<Method, MethodHandler> dispatch; public CountingFeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch for %s", target); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("equals".equals(method.getName())) { try { Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null; return equals(otherHandler); } catch (IllegalArgumentException e) { return false; } } else if ("hashCode".equals(method.getName())) { return hashCode(); } else if ("toString".equals(method.getName())) { return toString(); } RequestLine requestLine = method.getAnnotation(RequestLine.class); addStatistics(requestLine.value()); return dispatch.get(method).invoke(args); } @Override public boolean equals(Object obj) { if (obj instanceof CountingFeignInvocationHandler) { CountingFeignInvocationHandler other = (CountingFeignInvocationHandler) obj; return target.equals(other.target); } return false; } @Override public int hashCode() { return target.hashCode(); } @Override public String toString() { return target.toString(); } }

小心并检查假装配置是否不复杂,在这种情况下根据需要扩展类。

以上是关于在Feign RequestInterceptor / RequestTemplate中访问URITemplate或RequestLine值的主要内容,如果未能解决你的问题,请参考以下文章

如何排除特定 Spring Cloud Feign 客户端的 RequestInterceptor?

为什么我在spring微服务中实现了feign.RequestInterceptor接口,但是没有拦截

Feign 应用之 RequestInterceptor 拦截器,超实用指南

在 Feign RequestInterceptor / RequestTemplate 中访问 URITemplate 或 RequestLine 值

Feign解决服务之间调用传递token

Feign统一设置header