Feign配置请求头及支持Https协议
背景
最近跟第三方对接,请求头需要特殊处理,同时是 Https 协议。
第三方提供的是使用 OkHttp 调用。同时呢,使用 OkHttp 封装了调用和返回值。
今天对项目代码进行审查的时候,想着还是把这个替换调吧,实现起来更加的优雅。
Feign配置请求头
FeignParamsInterceptor 这个类实现了 RequestInterceptor ,可以实现对请求进行拦截处理。
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
|
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import feign.RequestInterceptor; import feign.RequestTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.UnsupportedEncodingException; /** * @Description feign参数拦截 */ @Component public class FeignParamsInterceptor implements RequestInterceptor { private static final Logger logger = LoggerFactory.getLogger(FeignParamsInterceptor. class ); private static final String loanUrl = "x/" ; private static final String accountUrl = "y/" ; @Value ( "${xxxx}" ) private String clientSecret; @Value ( "${yyyy}" ) private String clientId; @Override public void apply(RequestTemplate requestTemplate) { String url = requestTemplate.url(); if (url.contains(loanUrl) || url.contains(accountUrl)) { //获取请求体 byte [] body = requestTemplate.body(); JSONObject params; try { params = JSON.parseObject( new String(body, requestTemplate.charset() == null ? "utf-8" : requestTemplate.charset().name())); //设置请求体 requestTemplate.body(params.toJSONString()); requestTemplate.header( "xx" , CryptoEncrypt.signBytes(params.toJSONString().getBytes(), clientSecret.getBytes())); requestTemplate.header( "yyyy" , clientId); requestTemplate.header( "Content-Type" , "application/json;charset=utf-8" ); } catch (UnsupportedEncodingException e) { logger.info(e.getMessage(), e); } } } } |
Feign支持Https协议
如下 FeignHttpsConfig 类内容:这个方案呢,目前是可以实现效果的。具体的内容是否可以简化,优化。这个还没有具体的研究。
本文的解决方案是有问题的。请点击这里
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
import feign.Client; import feign.Feign; import feign.Logger; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.net.ssl.*; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.security.KeyStore; import java.security.Principal; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class FeignHttpsConfig { @Bean public Feign.Builder feignBuilder() { final Client trustSSLSockets = client(); return Feign.builder().client(trustSSLSockets); } @Bean public Client client(){ return new Client.Default( TrustingSSLSocketFactory.get(), new NoopHostnameVerifier()); } } class TrustingSSLSocketFactory extends SSLSocketFactory implements X509TrustManager, X509KeyManager { private static final Map<String, SSLSocketFactory> sslSocketFactories = new LinkedHashMap<String, SSLSocketFactory>(); private static final char [] KEYSTORE_PASSWORD = "password" .toCharArray(); private final static String[] ENABLED_CIPHER_SUITES = { "TLS_RSA_WITH_AES_256_CBC_SHA" }; private final SSLSocketFactory delegate; private final String serverAlias; private final PrivateKey privateKey; private final X509Certificate[] certificateChain; private TrustingSSLSocketFactory(String serverAlias) { try { SSLContext sc = SSLContext.getInstance( "SSL" ); sc.init( new KeyManager[] { this }, new TrustManager[] { this }, new SecureRandom()); this .delegate = sc.getSocketFactory(); } catch (Exception e) { throw new RuntimeException(e); } this .serverAlias = serverAlias; if (serverAlias.isEmpty()) { this .privateKey = null ; this .certificateChain = null ; } else { try { KeyStore keyStore = loadKeyStore(TrustingSSLSocketFactory. class .getResourceAsStream( "/keystore.jks" )); this .privateKey = (PrivateKey) keyStore.getKey(serverAlias, KEYSTORE_PASSWORD); Certificate[] rawChain = keyStore.getCertificateChain(serverAlias); this .certificateChain = Arrays.copyOf(rawChain, rawChain.length, X509Certificate[]. class ); } catch (Exception e) { throw new RuntimeException(e); } } } public static SSLSocketFactory get() { return get( "" ); } public synchronized static SSLSocketFactory get(String serverAlias) { if (!sslSocketFactories.containsKey(serverAlias)) { sslSocketFactories.put(serverAlias, new TrustingSSLSocketFactory(serverAlias)); } return sslSocketFactories.get(serverAlias); } static Socket setEnabledCipherSuites(Socket socket) { SSLSocket. class .cast(socket).setEnabledCipherSuites(ENABLED_CIPHER_SUITES); return socket; } private static KeyStore loadKeyStore(InputStream inputStream) throws IOException { try { KeyStore keyStore = KeyStore.getInstance( "JKS" ); keyStore.load(inputStream, KEYSTORE_PASSWORD); return keyStore; } catch (Exception e) { throw new RuntimeException(e); } finally { inputStream.close(); } } @Override public String[] getDefaultCipherSuites() { return ENABLED_CIPHER_SUITES; } @Override public String[] getSupportedCipherSuites() { return ENABLED_CIPHER_SUITES; } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return setEnabledCipherSuites(delegate.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException { return setEnabledCipherSuites(delegate.createSocket(host, port)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return setEnabledCipherSuites(delegate.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { return setEnabledCipherSuites(delegate.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return setEnabledCipherSuites(delegate.createSocket(address, port, localAddress, localPort)); } @Override public X509Certificate[] getAcceptedIssuers() { return null ; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} @Override public String[] getClientAliases(String keyType, Principal[] issuers) { return null ; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { return null ; } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { return null ; } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { return serverAlias; } @Override public X509Certificate[] getCertificateChain(String alias) { return certificateChain; } @Override public PrivateKey getPrivateKey(String alias) { return privateKey; } } |
Feign client 设置请求头信息
Feign client端
1
2
3
4
5
6
7
8
9
10
11
|
@FeignClient (url = "${test.url}" , name = "cclient" ,configuration= ClientConfiguration. class ,fallback = APIClientFallback. class ) public interface APIClient { @RequestMapping (method = RequestMethod.POST, value = "/check/test" ) String checkResult( @RequestParam ( "sendTelNo" ) String sendTelNo, @RequestParam ( "certType" ) String certType, @RequestParam ( "certCode" ) String certCode, @RequestParam ( "userName" ) String userName); @RequestMapping (method = RequestMethod.POST, value = "/userstaus/test" ) String inusetime( @RequestParam ( "sendTelNo" ) String sendTelNo); @RequestMapping (method = RequestMethod.POST, value = "/userstaus/test" ) String offnetIdentify( @RequestParam ( "sendTelNo" ) String sendTelNo, @RequestParam ( "date" ) String date); |
配置文件 application-dev.yml
1
2
3
|
test: url: https://xxxxxx:8243/test tokenId: 11111112222222 |
feign configuration 这里配置全局的请求头和token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Configuration public class ClientConfiguration { @Value ( "${test.tokenId}" ) private String tokenId; @Bean public RequestInterceptor headerInterceptor() { return new RequestInterceptor(){ @Override public void apply(RequestTemplate template) { List<String> authorizationList = Lists.newArrayList( "Bearer " +tokenId); List<String> contentTypeList = Lists.newArrayList( "application/x-www-form-urlencoded;charset=utf-8" ); Map<String, Collection<String>> headers =ImmutableMap.of( "Authorization" , authorizationList, "Content-Type" , contentTypeList); template.headers(headers); } }; } |
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
|
@Component public class APIClientFallback implements APIClient{ @Override public String checkResult(String sendTelNo, String certType, String certCode, String userName) { return toJsonString(); } @Override public String inusetime(String sendTelNo) { return toJsonString(); } @Override public String offnetIdentify(String sendTelNo, String date) { return toJsonString(); } private String toJsonString() { BaseResult resultVo = new BaseResult(); resultVo.renderStatus(ResultTypeEnum.SERVICE_ERROR); ObjectMapper mapper = new ObjectMapper(); try { return mapper.writeValueAsString(resultVo); } catch (JsonProcessingException e) { e.printStackTrace(); } return null ; } } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/H_Rhui/article/details/99710874