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
查看更多关于使用Feign配置请求头以及支持Https协议的详细内容...