评论

收藏

[Java] SpringBoot feign动态设置数据源(https请求)

编程语言 编程语言 发布于:2021-12-07 12:12 | 阅读数:335 | 评论:0

这篇文章主要介绍了SpringBoot如何在运行时feign动态添加数据源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
目录

  • 1、背景
  • 2、代码

    • 2.2、 编写请求方法
    • 2.3、发送请求

  • 总结:

1、背景
在使用springboot-feign/spingcloud-feign时,需要在启动springboot的时候,注入的方式将feigncofing配置好,也就是说项目启动以后只能有一个数据源,且不能修改,在网上找了很多资料没有找到解决方案(网上应该有,只是我没有找到),后面只能是硬着头皮看源码,问题解决,在此记录一下,希望可以帮到有缘人

2、代码
其实在这里用的原生的feign,并不是springboot/springcloud封装的feign,废话不说,上代码
public <T> T getRemote(Class<T> apiType, String url, String apiCert, String certPassWord) {
  // apiCert 是p12文件读了以后的数据,可以把p12文件放在本地,我这里是伪代码了
  feign.Client.Default client = FeignClient(apiCert, certPassWord);
  Decoder decoder =
    (response, type) -> {
      final String result =
        IOUtils.toString(response.body().asInputStream(), StandardCharsets.UTF_8);
      if (String.class.getName() == type.getTypeName()) {
      return result;
      }
      try {
      return JSON.parseObject(result, type);
      } catch (Exception e) {
      log.error("json parse exception");
      }
      return result;
    };
  ErrorDecoder errorDecoder =
    (methodKey, response) -> {
      try {
      final String result =
        IOUtils.toString(response.body().asInputStream(), StandardCharsets.UTF_8);
      log.info("feign client decoder response body : {}", result);
      throw new SysStatusException(response.status(), result);
      } catch (IOException e) {
      log.info("feign client decoder response error {}", e);
      }
      throw new BizStatusException(response.status(), BizCommMessage.ERROR_MSG);
    };
  T remote =
    Feign.builder()
      .decoder(decoder)
      .errorDecoder(errorDecoder)
      .client(url)
      .target(apiType, client);
  return remote;
  }
public Client getFeignClient(String apiCert, String certPassWord) {
  final SSLSocketFactory sslSocketFactory = getSSLSocketFactory(apiCert, certPassWord);
  feign.Client.Default aDefault = new Client.Default(sslSocketFactory, new NoopHostnameVerifier());
  return aDefault;
  }
public static SSLSocketFactory getSSLSocketFactory(String apiCert, String certPassWord) {
  byte[] bytes = apiCert.getBytes();
  try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
    KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
    keyStore.load(inputStream, certPassWord.toCharArray());
    SSLContext sslContext =
      SSLContexts.custom()
        // 忽略掉对服务器端证书的校验,特别重要,被这行代码坑过
        .loadTrustMaterial((TrustStrategy) (chain, authType) -> true)
        .loadKeyMaterial(keyStore, certPassWord.toCharArray())
        .build();
    return sslContext.getSocketFactory();
  } catch (IOException e) {
    log.error("=======init feign client throw IOException======={}", e);
  } catch (KeyStoreException e) {
    log.error("=======init feign client throw KeyStoreException======={}", e);
  } catch (UnrecoverableKeyException e) {
    log.error("=======init feign client throw UnrecoverableKeyException======={}", e);
  } catch (CertificateException e) {
    log.error("=======init feign client throw CertificateException======={}", e);
  } catch (NoSuchAlgorithmException e) {
    log.error("=======init feign client throw NoSuchAlgorithmException======={}", e);
  } catch (KeyManagementException e) {
    log.error("=======init feign client throw KeyManagementException======={}", e);
  }
  return null;
  }
2.2、 编写请求方法
public interface TestRemote {
  @Override
  @RequestLine("POST /apis/{test}/query")
  @Headers({"Content-Type: application/json","Accept: application/json"})
  @Body("{body}")
  String query(@Param("test") String test, @Param("body") String body);
}
2.3、发送请求
public static void main(String[] args) {
   TestRemote testRemote = getRemote(TestRemote.class,String url, String apiCert, String certPassWord);
  testRemote.query("test","{"id":1}");
  }
总结:
这样就可以根据前端传来的参数,切换不同的客户端
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注CodeAE代码之家的更多内容!
原文链接:https://blog.csdn.net/weixin_42349879/article/details/119894105C

关注下面的标签,发现更多相似文章