1、背景
在使用springboot-feign/spingcloud-feign时,需要在启动springboot的时候,注入的方式将feigncofing配置好,也就是说项目启动以后只能有一个数据源,且不能修改,在网上找了很多资料没有找到解决方案(网上应该有,只是我没有找到),后面只能是硬着头皮看源码,问题解决,在此记录一下,希望可以帮到有缘人
2、代码
其实在这里用的原生的feign,并不是springboot/springcloud封装的feign,废话不说,上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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、 编写请求方法
1 2 3 4 5 6 7 | 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、发送请求
1 2 3 4 | public static void main(String[] args) { TestRemote testRemote = getRemote(TestRemote. class ,String url, String apiCert, String certPassWord); testRemote.query( "test" , "{\"id\":1}" ); } |
总结:
这样就可以根据前端传来的参数,切换不同的客户端
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注自学编程网的更多内容!
- 本文固定链接: https://zxbcw.cn/post/220818/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)