使用Feign配置請求頭以及支持Https協(xié)議
Feign配置請求頭及支持Https協(xié)議
背景
最近跟第三方對接,請求頭需要特殊處理,同時是 Https 協(xié)議。
第三方提供的是使用 OkHttp 調(diào)用。同時呢,使用 OkHttp 封裝了調(diào)用和返回值。
今天對項目代碼進行審查的時候,想著還是把這個替換調(diào)吧,實現(xiàn)起來更加的優(yōu)雅。
Feign配置請求頭
FeignParamsInterceptor 這個類實現(xiàn)了 RequestInterceptor ,可以實現(xiàn)對請求進行攔截處理。
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參數(shù)攔截 ?*/ @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())); ? ? ? ? ? ? ? ? //設(shè)置請求體 ? ? ? ? ? ? ? ? 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協(xié)議
如下 FeignHttpsConfig 類內(nèi)容:這個方案呢,目前是可以實現(xiàn)效果的。具體的內(nèi)容是否可以簡化,優(yōu)化。這個還沒有具體的研究。
本文的解決方案是有問題的。請點擊這里
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 設(shè)置請求頭信息
Feign client端
@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
test: ? ? ? url: https://xxxxxx:8243/test ? ? ? tokenId: 11111112222222?
feign configuration 這里配置全局的請求頭和token
@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 異常處理
@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; ?? ?} }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Nexus使用nginx代理實現(xiàn)支持HTTPS協(xié)議
- Spring Boot項目如何同時支持HTTP和HTTPS協(xié)議的實現(xiàn)
- Spring Boot應(yīng)用程序同時支持HTTP和HTTPS協(xié)議的實現(xiàn)方法
- SpringBoot2.0如何啟用https協(xié)議
- 關(guān)于Https協(xié)議和HttpClient的實現(xiàn)詳解
- startssl申請SSL證書 并且配置 iis 啟用https協(xié)議
- Java獲取http和https協(xié)議返回的json數(shù)據(jù)
- Linux下nginx配置https協(xié)議訪問的方法
- iOS9蘋果將原h(huán)ttp協(xié)議改成了https協(xié)議的方法
- apache中使用mod_gnutls模塊實現(xiàn)多個SSL站點配置(多個HTTPS協(xié)議的虛擬主機)
- https協(xié)議詳解
相關(guān)文章
Java matches類,Pattern類及matcher類用法示例
這篇文章主要介紹了Java matches類,Pattern類及matcher類用法,結(jié)合實例形式分析了java matches類,Pattern類及matcher類針對字符串常見操作技巧與相關(guān)注意事項,需要的朋友可以參考下2019-03-03Java 中 Date 與 Calendar 之間的編輯與轉(zhuǎn)換實例詳解
這篇文章主要介紹了Java 中 Date 與 Calendar 之間的編輯與轉(zhuǎn)換 ,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-07-07Gradle build 報錯:Received status code 400 from server
這篇文章主要介紹了Gradle build 報錯:Received status code 400 from server,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Python基礎(chǔ)之如何使用multiprocessing模塊
今天帶大家學(xué)習(xí)python多進程的相關(guān)知識,文中對multiprocessing模塊的使用作了非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06Java?web訪問http://localhost:8080/xx/xx.jsp報404錯誤問題的解決方法
這篇文章主要給大家介紹了關(guān)于Java?web訪問http://localhost:8080/xx/xx.jsp報404錯誤問題的解決方法,很多小伙伴在剛開始用Springboot整合jsp開發(fā)時都會遇到這個問題, 按照別人的教程一步一步搭建,但就是會報404,文中介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04