项目中使用feign client对接硬件的http接口,这样可以利用Feign Client的好处,但是跟一般的微服务不一样,每个同型号的硬件接口都是一样的,但是硬件的数据和状态是不一样的,有的请求只能发送到指定的硬件。 本文介绍如何让feign client支持动态调用服务器
实现
- 动态替换URL
利用线程私有变量,动态替换URL,其实这种方式不但可以替换URL和可以只替换name,这样还可以实现动态名字
public class DynamicFeignClientInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
Target<?> target = template.feignTarget();
if (!Strings.isNullOrEmpty(THREAD_LOCAL_URL.get())) {
//替换成线程私有URL
String newUrl = target.url().replace(target.url(), THREAD_LOCAL_URL.get());
Target.HardCodedTarget<?> newTarget = new Target.HardCodedTarget<>(target.type(), target.name(), newUrl);
newTarget.apply(template);
}
}
/**
* 线程私有的URL.
*/
private static final ThreadLocal<String> THREAD_LOCAL_URL = new ThreadLocal<>();
public static void setUrl(String newUrl) {
THREAD_LOCAL_URL.set(newUrl);
}
public static void removeUrl() {
THREAD_LOCAL_URL.remove();
}
}
- FeignClient接口定义
如果使用动态名字,就不能设置
url
,如果要用url
就必须设置,不能为空
@FeignClient(value = "DYNAMIC-CLIENT", url = "DYNAMIC-CLIENT", configuration = WxFeignConfiguration.class)
public interface HwNvrServiceApi {
/**
* 登录前设备信息.
*
* @return 设备信息
*/
@PostMapping("API/Login/Range")
HwNetResult<ObjectNode> deviceInfoBeforeLogin();
}
- FeignClient配置
public class WxFeignConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
DynamicFeignClientInterceptor dynamicFeignClientInterceptor() {
return new DynamicFeignClientInterceptor();
}
}
使用
DynamicFeignClientInterceptor.setUrl("https://www.baidu.com:443");
HwNetResult<ObjectNode> jsonNodes = hwNvrServiceApi.deviceInfoBeforeLogin();
DynamicFeignClientInterceptor.removeUrl();