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

目录
  • Feign配置请求头及支持Https协议
    • 背景
    • Feign配置请求头
    • Feign支持Https协议
  • Feignclient设置请求头信息
    • Feignclient端
    • 配置文件application-dev.yml
    • feignconfiguration这里配置全局的请求头和token
    • feign异常处理

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

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

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

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

(0)

相关推荐

  • 解决Spring Cloud Feign 请求时附带请求头的问题

    问题描述 Feign 在请求时是不会将 request 的请求头带着请求的,导致假如 Feign 调用的接口需要请求头的信息,比如当前用户的 token 之类的就获取不到 解决方案 FeignConfiguration 通过实现 Feign 的 RequestInterceptor 将从上下文中获取到的请求头信息循环设置到 Feign 请求头中. /** * feign 配置文件 * 将请求头中的参数,全部作为 feign 请求头参数传递 * @author: linjinp * @create

  • Spring 使用 feign时设置header信息的操作

    Spring feign时设置header信息 最近使用 SpringBoot 项目,把一些 http 请求转为 使用 feign方式.但是遇到一个问题:个别请求是要设置header的. 于是,查看官方文档和博客,大致推荐两种方式.也可能是我没看明白官方文档. 接口如下: @FeignClient(url ="XX_url", value ="XXService") public interface XXService { @RequestMapping(value

  • 使用feign服务调用添加Header参数

    feign添加Header参数 @Configuration public class FeignConfiguration implements RequestInterceptor { private static final Logger logger = LoggerFactory.getLogger(FeignConfiguration.class); @Override public void apply(RequestTemplate template) { ServletRequ

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

    目录 Feign配置请求头及支持Https协议 背景 Feign配置请求头 Feign支持Https协议 Feignclient设置请求头信息 Feignclient端 配置文件application-dev.yml feignconfiguration这里配置全局的请求头和token feign异常处理 Feign配置请求头及支持Https协议 背景 最近跟第三方对接,请求头需要特殊处理,同时是 Https 协议. 第三方提供的是使用 OkHttp 调用.同时呢,使用 OkHttp 封装了调用

  • SpringCloud Feign转发请求头(防止session失效)的解决方案

    微服务开发中经常有这样的需求,公司自定义了通用的请求头,需要在微服务的调用链中转发,比如在请求头中加入了token,或者某个自定义的信息uniqueId,总之就是自定义的一个键值对的东东,A服务调用B服务,B服务调用C服务,这样通用的东西如何让他在一个调用链中不断地传递下去呢?以A服务为例: 方案1 最傻的办法,在程序中获取,调用B的时候再转发,怎么获取在Controller中国通过注解获取,或者通过request对象获取,这个不难,在请求B服务的时候,通过注解将值放进去即可:简代码如下: 获取

  • 使用Feign传递请求头信息(Finchley版本)

    目录 Feign传递请求头信息 实现RequestInterceptor接口 注册配置 Feign调用微服务传递header请求头 Feign传递请求头信息 在我之前的文章服务网关Spring Cloud Zuul中,将用户的登录id放在了请求头中传递给内部服务. 但是当内部服务之间存在feign调用时,那么请求头信息会在feign请求的时候传递吗?不会,请求的头信息和请求参数都不会进行传递. 但是我们可以通过通过实现RequestInterceptor接口,完成对所有的Feign请求,传递请求

  • 关于axios配置请求头content-type实例详解

    目录 前言 axios配置请求头content-type方法如下: 补充:axios 根据接口设置不同的content-type 总结 前言 现在网上可能发送Ajax请求有很多种插件,每种用法可能略有差异,大家只需挑选一种自己喜欢的即可.毕竟现在还有很多人使用jQuery,$.ajax用法也是很多了. axios配置请求头content-type方法如下: axios 是Ajax的一个插件,axios虽然是一个插件,但是我们不需要通过Vue.use(axios)来使用,下载完成后,只需在项目中引

  • Nexus使用nginx代理实现支持HTTPS协议

    背景 公司全部网站需要支持 HTTPS 协议,在阿里云负载均衡配置 SSL 证书后,导致 Nexus 的 HTTPS 访问出错. 网站访问路径: 域名解析到阿里云的负载均衡,负载均衡配置 80 端口强转 443 端口,443 端口配置 SSL 证书,并转发到内网 nginx,内网的 nginx 再代理 Nexus 服务. 解决 浏览器 HTTPS 访问 Nexus 的 Console 报错信息: 报错信息大致意思是:HTTPS 访问的页面上不允许出现 HTTP 请求. 解决方法: 在 nginx

  • 简单聊一聊axios配置请求头content-type

    目录 前言 开始 使用 总结 前言 现在前端开发中需要通过Ajax发送请求获取后端数据是很普遍的一件事情了,鉴于我平时在撸码中用的是vue技术栈,今天这里来谈谈我们常用的发Ajax请求的一个插件—axios. > 现在网上可能发送Ajax请求有很多种插件,每种用法可能略有差异,大家只需挑选一种自己喜欢的即可.毕竟现在还有很多人使用jQuery,$.ajax用法也是很多了. 开始 因为需要用到axios插件,所以我们现在项目种下载依赖 npm install axios -S axios虽然是一个

  • Linux下nginx配置https协议访问的方法

    一.配置nginx支持https协议访问,需要在编译安装nginx的时候添加相应的模块--with-http_ssl_module 查看nginx编译参数:/usr/local/nginx/sbin/nginx -V 如下所示: configure arguments: --prefix=/usr/local/nginx --with-google_perftools_module --without-http_memcached_module --user=www --group=www --

  • 详解node如何让一个端口同时支持https与http

    众所周知node是一个高性能的web服务器,使用它可以很简单的创建一个http或https的服务器. 比如一个很简单的http服务器: var http = require('http'); var https = require('https'); var httpPort = 3345; var server = http.createServer(function(req, res){ res.writeHead(200, {'Content-Type': 'text/plain'});

  • IOS开发 支持https请求以及ssl证书配置详解

    IOS开发 支持https请求以及ssl证书配置详解 前言: 众所周知,苹果有言,从2017年开始,将屏蔽http的资源,强推https 楼主正好近日将http转为https,给还没动手的朋友分享一二 一.证书准备 1.证书转换 在服务器人员,给你发送的crt证书后,进到证书路径,执行下面语句 // openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der 这样你就可以得到cer类型的证书了.双击,导入电脑. 2.证书放入工程 1.可以直接把转换好

随机推荐