好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用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

查看更多关于使用Feign配置请求头以及支持Https协议的详细内容...

  阅读:19次