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

