服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 使用Feign配置请求头以及支持Https协议

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

2022-08-31 12:17Hubert-hui Java教程

这篇文章主要介绍了使用Feign配置请求头以及支持Https协议,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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

延伸 · 阅读

精彩推荐
  • Java教程springboot项目事务标签验证

    springboot项目事务标签验证

    本文主要介绍了springboot项目事务标签验证,文中通过示例代码介绍的非常详细,详细的介绍了不加事务标签和加事物标签的使用,需要的朋友们下面随着小...

    软件老王5822021-10-07
  • Java教程java多线程编程之Synchronized块同步方法

    java多线程编程之Synchronized块同步方法

    这篇文章主要介绍了java多线程编程之Synchronized块同步方法,synchronized关键字又称同步锁,当方法执行完后,会自动释放锁锁,只有一个线程能进入此方法,...

    lijiao3762020-03-06
  • Java教程Spring MVC---数据绑定和表单标签详解

    Spring MVC---数据绑定和表单标签详解

    本篇文章主要介绍了Spring MVC---数据绑定和表单标签详解,具有一定的参考价值,有兴趣的可以了解一下。...

    best.lei3152020-07-26
  • Java教程一小时迅速入门Mybatis之增删查改篇

    一小时迅速入门Mybatis之增删查改篇

    这篇文章主要介绍了迅速入门Mybatis之增删查改篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    grace.free10232021-12-31
  • Java教程Spring的实例工厂方法和静态工厂方法实例代码

    Spring的实例工厂方法和静态工厂方法实例代码

    这篇文章主要介绍了Spring的实例工厂方法和静态工厂方法实例代码,具有一定借鉴价值,需要的朋友可以参考下...

    zhupengqq11742021-03-17
  • Java教程Jmeter跨线程组共享cookie过程图解

    Jmeter跨线程组共享cookie过程图解

    这篇文章主要介绍了Jmeter跨线程组共享cookie过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以...

    测试逍遥子6482020-07-04
  • Java教程Java网络编程基础详解

    Java网络编程基础详解

    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。本文介绍了一些网络编程基础的概念,并用Java来实现TCP和UDP的Socke...

    我永远信仰10642021-11-21
  • Java教程基于NIO的Netty网络框架(详解)

    基于NIO的Netty网络框架(详解)

    下面小编就为大家带来一篇基于NIO的Netty网络框架(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Java之家5582020-11-12