文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用Feign配置请求头以及支持Https协议

2024-04-02 19:55

关注

Feign配置请求头及支持Https协议

背景

最近跟第三方对接,请求头需要特殊处理,同时是 Https 协议。

第三方提供的是使用 OkHttp 调用。同时呢,使用 OkHttp 封装了调用和返回值。

今天对项目代码进行审查的时候,想着还是把这个替换调吧,实现起来更加的优雅。

Feign配置请求头

FeignParamsInterceptor 这个类实现了 RequestInterceptor ,可以实现对请求进行拦截处理。

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;
 

@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 类内容:这个方案呢,目前是可以实现效果的。具体的内容是否可以简化,优化。这个还没有具体的研究。

本文的解决方案是有问题的。请点击这里

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端

@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;
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯