feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务

这篇具有很好参考价值的文章主要介绍了feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近接手一个项目,各子工程之间通过feign调用;各服务部署在K8S上,通过nacos管理配置;由于服务部署的机器无法开放端口等原因,导致本机服务与测试环境网络端口无法互通,故需要重写feign的调用地址;个人总结的方法有以下几种:

目录

 第一种:feignclient配置URL

第二种:实现RequestInterceptor接口;

第三种:重写feign的client的execute方法;


 第一种:feignclient配置URL

        在feignclient里写一个固定地址或者写一个可配置的地址,这样可以在配置文件里指定,这种方式在创建feign客户端的时候就需要规划好。

        1.1 固定地址

@FeignClient(name = "feignCustomerService", url = "http://localhost:8080")
public interface FeignCustomerService {
    /**
     * 请求客户的接口
     */
    @RequestMapping(value = "order/update", method = RequestMethod.POST)
    @Headers(value = "Content-Type: application/json")
    OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);
 
}

1.2 可配置的地址

@FeignClient(name = "feignCustomerService", url = "${customer.url}")
public interface FeignCustomerService {
   
    @RequestMapping(value = "test/list", method = RequestMethod.POST)
    @Headers(value = "Content-Type: application/json")
    OrderHttpResponse updateTest(@RequestBody OrderUpdateDTO orderUpdateDTO);
 
}

配置文件配置地址

customer.url=http://localhost:8080

第二种:实现RequestInterceptor接口;

        这种方式具有局限性,在nacos上注册的服务IP与本机IP不一致的时候(连接VPN)可能依旧调不通服务,但是实现RequestInterceptor接口可以处理全局请求(header,身份认证等)

@Component
public class Oauth2TokenRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        // 获取请求中的消息头
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String requestHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isNotBlank(requestHeader) && requestHeader.startsWith("Bearer ")) {
            // 将消息头塞入到请求模板中
            requestTemplate.header(HttpHeaders.AUTHORIZATION, requestHeader);
        }
        //重写URL,访问指定服务
        String url = target.url();
        String newUrl = "http://localhost:8080";
        template.target(newUrl );
    }
}

第三种:重写feign的client的execute方法;

        这种方式可以自定义负载均衡的策略,也可以自定义访问指定服务IP,这里以FeignBlockingLoadBalancerClient为例

配置类

package com.***.redirect;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.util.Map;

@Getter
@Setter
@RefreshScope
@ConfigurationProperties("localbalance")
@Component
public class LocalFeignPerpreties {
    private Boolean enable;
    private Map<String,String> rule;
}

配置文件配置内容:

localbalance:
  enable: true
  rule:
    aiflow-sys: http://IP:8888/SERVICE
    aiflow-auth: http://IP:8888/SERVICE

重写FeignBlockingLoadBalancerClient 的execute方法

package com.***.redirect;

import feign.Client;
import feign.Request;
import feign.RequestTemplate;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.*;

//@ConditionalOnBean
//@Primary
@Slf4j
public class LocalBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient {
    private Client delegate;
    private BlockingLoadBalancerClient loadBalancerClient;
    @Autowired
    private LocalFeignPerpreties localFeignPerpreties;

    public LocalBlockingLoadBalancerClient(Client delegate,
                                           BlockingLoadBalancerClient loadBalancerClient) {
        super(delegate, loadBalancerClient);
        this.delegate = delegate;
        this.loadBalancerClient = loadBalancerClient;
    }

    @Override
    public Response execute(Request request, Request.Options options) throws IOException {
        try {
            log.info("feign -> 配置化客户端");
            Boolean enable = localFeignPerpreties.getEnable();
            if (enable) {
                String url = request.url();
                RequestTemplate requestTemplate = request.requestTemplate();
                String name = requestTemplate.feignTarget().name();
                Map<String, String> urlMap = localFeignPerpreties.getRule();
                if (urlMap != null && urlMap.containsKey(name)) {
                    URI uri = URI.create(url);
                    StringBuffer strbuf = new StringBuffer();
                    strbuf.append(urlMap.get(name)).append(uri.getPath());
                    if (StringUtils.isNotBlank(uri.getQuery())) {
                        strbuf.append("?").append(uri.getQuery());
                    }
                    requestTemplate.target(urlMap.get(name));
                    Map<String, Collection<String>> headers = request.headers();
                    Map<String, Collection<String>> newheaders = new HashMap<>();
                    //处理请求头
                    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                    HttpServletRequest attributesRequest = attributes.getRequest();
                    Enumeration<String> headerNames = attributesRequest.getHeaderNames();
                    if (headerNames != null) {
                        while (headerNames.hasMoreElements()) {
                            String element = headerNames.nextElement();
                            String elementVal = attributesRequest.getHeader(element);
                            newheaders.put(element, new ArrayList<String>() {{
                                add(elementVal);
                            }});
                        }
                    }
                    //构建新的request
                    Request newRequest = buildRequest(request, strbuf.toString(), newheaders);
                    return super.getDelegate().execute(newRequest, options);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("feign -> 默认客户端");
        return super.execute(request, options);
    }

    protected Request buildRequest(Request request,
                                   String reconstructedUrl,
                                   Map<String, Collection<String>> headers) {
        return Request.create(request.httpMethod(), reconstructedUrl, headers,
                request.body(), Charset.forName("UTF-8"), request.requestTemplate());
    }

}

使配置类和重写的client生效

package com.***.redirect;

import feign.Client;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@ConditionalOnProperty(prefix = ReBalancerProperties.prefix,name = "enable",havingValue = "true")
@Configuration
@EnableConfigurationProperties(value = {LocalFeignPerpreties.class})
public class ReBalancerConfiguration {

    @Bean
    public Client feignReBalancer(BlockingLoadBalancerClient discoveryClient) {

        return new LocalBlockingLoadBalancerClient(new Client.Default(null, null),
                discoveryClient);
    }
}

        到这里基本上可以满足重写feign URL的需求了,这个前提条件是代码在application启动类的下一级,如果不在启动类的同级或者下一级,是无法扫描到相关类的,这时我们可以注解完成扫描,需要在启动类上加上相关注解文章来源地址https://www.toymoban.com/news/detail-767313.html

package com.***.annotation;

import com.***.ReBalancerConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.context.annotation.Import;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(ReBalancerConfiguration.class)
@AutoConfigurationPackage
public @interface EnableLocalFeignClient {
}

到了这里,关于feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • php第三方阿里云接口

    阿里云 OpenAPI 开发者门户

    2024年02月15日
    浏览(29)
  • 【黑马头条之内容安全第三方接口】

    本笔记内容为黑马头条项目的文本-图片内容审核接口部分 目录 一、概述 二、准备工作 三、文本内容审核接口 四、图片审核接口 五、项目集成 内容安全是识别服务,支持对图片、视频、文本、语音等对象进行多样化场景检测,有效降低内容违规风险。 目前很多平台都支持

    2024年02月15日
    浏览(51)
  • 对接 Web Service第三方接口

    这次也是头一次接触对接第三方WebService接口,这技术都很老了,使用postman测试的时候还找了半天资料🤣。 一般来说第三方都会限制ip这些,需要注意的是,给到的接口地址是能用公网进行访问的哦。 1、拿到接口路径 http://111.111.11.1:111/services/infoWebService?wsdl 这个当然是不可

    2023年04月11日
    浏览(36)
  • OpenAI 接口API的第三方代理

    OpenAI推出了针对开发者的API接口,这是供程序代码去调用的,不是面向普通人的。我们经常看到的国内版ChatGPT,就是对API接口的界面包装再出售会员。 目前,公开对外使用的是GPT-3.5模型的API接口,GPT-4模型的接口处于测试阶段,开发者需要申请权限加入等待列表,审核通过

    2024年02月07日
    浏览(36)
  • 仅仅是调用第三方接口那么简单吗?

    最近有个项目需要本地处理之后,然后调用第三方接口,本来开始觉得很简单得事情,不就是调用第三方接口吗?但是却一波三折。 首先有了下面的第一版的设计。 这个设计很简单,也是最容易想到的。主要有下面几步 1、本地处理; 2、调用第三方接口; 3、本地日志打印

    2024年02月06日
    浏览(48)
  • 我调用第三方接口遇到的13大坑

    在实际工作中,我们经常需要在项目中调用第三方API接口,获取数据,或者上报数据,进行数据交换和通信。 那么,调用第三方API接口会遇到哪些问题?如何解决这些问题呢? 这篇文章就跟大家一起聊聊第三方API接口的话题,希望对你会有所帮助。   一般我们在第一次对接

    2023年04月16日
    浏览(45)
  • SpringBoot案例 调用第三方接口传输数据

    最近再写调用三方接口传输数据的项目,这篇博客记录项目完成的过程,方便后续再碰到类似的项目可以快速上手 项目结构: 这里主要介绍HttpClient发送POST请求工具类和定时器的使用,mvc三层架构编码不做探究 pom.xml application-dev.yml Constast utils scheduled 该定时任务每10秒执行一

    2024年02月12日
    浏览(46)
  • java对接第三方接口的三种方式

    在日常工作中,经常需要跟第三方系统对接,我们做为客户端,调用他们的接口进行业务处理,常用的几种调用方式有: 1.原生的Java.net.HttpURLConnection(jdk); 2.再次封装的HttpClient、CloseableHttpClient(Apache); 3.Spring提供的RestTemplate; 当然还有其他工具类进行封装的接口,比

    2024年04月28日
    浏览(42)
  • hutool的httpUtil的使用(访问第三方接口)

    以下仅为自己项目中所写并能够跑通 有问题留言 如若不对 请指出告知一下

    2024年02月06日
    浏览(41)
  • Java调用第三方http接口的常用方式

    前言 一、通过JDK网络类Java.net.HttpURLConnection 二、通过apache common封装好的HttpClient 三、通过Spring的RestTemplate 总结 今天项目需要接口互相调用,就看了一下这几个调用的方式 通过java.net包下的原生java.api提供的http请求 使用步骤: 通过统一的资源定位器(java.net.URL)获取连接器(java.

    2024年02月08日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包