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://blog.csdn.net/weixin_42349879/article/details/119894105C