信息发布→ 登录 注册 退出

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

发布时间:2026-01-11

点击量:
目录
  • 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}");
      }
    

    总结:

    这样就可以根据前端传来的参数,切换不同的客户端

    本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!