SpringCloud使用FeignClient

背景

公司使用的是SpringCloud微服务,最近刚刚引进两个服务之间的Feign调用,所以写下这篇文章作为记录,后续会在此专栏下写几遍SpringCloud的搭建过程。
本篇文章基于SpringCloud存在两个以上的注册服务,并且本文会附上,Feign之间调用出现的Token问题的解决方案。

使用方法

Feign的介绍

首先Spring Cloud OpenFeign官网简介(Feign官网

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.

Feign是声明性的Web服务客户端。它使编写Web服务客户端更加容易。要使用Feign,请创建一个接口并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并支持使用HttpMessageConvertersSpring Web中默认使用的注释。Spring Cloud集成了Eureka和Spring Cloud LoadBalancer,以在使用Feign时提供负载平衡的http客户端。

如何使用

搭建父子工程

详情请见我的其他文章(搭建父子工程
在这里插入图片描述
在这里插入图片描述

可以引入maven私服

详情看我的其他文章(还没写)

引入Feign依赖

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-openfeign</artifactId>
				<version>2.1.1.RELEASE</version>
			</dependency>

加入yml配置(可加可不加)

加入以下配置的主要原因是我在进行两个feign之间调用时发现总是莫名其妙的链接超时
原因是因为feign已经集成robbon,hystrix,调用在规定时间内达不到就会报上述错误,并且这个规定时间会很短
网上其他的文章有很多配置robbon以及hystrix的,我配置了如下feign也解决了问题

#调用超时延长
feign:
  client:
    config:
      default:
        connectTimeout: 10000
        readTimeout: 600000
  httpclient:
    connection-timeout: 30000

启动类注解

(@EnableFeignClients(basePackages = {“com.dachao.customer.api.*”}))

@SpringBootApplication
@EnableFeignClients(basePackages = {"com.dachao.customer.api.*"})
public class UserApplication{
public static void main(String[] args){
		SpringApplication.run(UserApplication.class, args);
	}
}

EnableFeignClients注解的参数是指
//@EnableFeignClients:表示需要调用B服务即需要将B服务的Feign的包路径进行扫描
//扫描多个包需要 @EnableFeignClients(basePackages = {“com.dachao.customer.api.*”,“com.dachao”})
这个服务的名字叫做A需要调用B服务的Feign,即需要将B的包名加入到EnableFeignClients注解上。
,说白了,调哪个服务的Api,就写哪个api的包名
即A启动类:

在这里插入图片描述

B服务包名
在这里插入图片描述

调用

这个操作需要项目中配置maven私服。
首先将我们的B服务的api的jar先deploy到我们的maven私服上。如下
在这里插入图片描述
然后A服务的Pom文件中引入B服务jar的依赖

 		<dependency>
            <groupId>com.dachao</groupId>
            <artifactId>customer-api</artifactId>
            <version>1.0.2-SNAPSHOT</version>
        </dependency>

将feign的代码写在 Api model中,那这个maven工程也就是这个jar可以在maven私服中其他的服务中自由引入,代码意思是,其他的服务调用这个接口时,会先去找在同一个注册中心的服务名称为commonService的服务,然后去调用这个服务的/sms/alisendmessage,代码中的path = "/sms"意思和控制器类上层的@RequestMapping的一样,为接口前缀,注:代码中的name = “commonService”,属性 name 和value功能一样

@FeignClient(name = "commonService", path = "/sms")
public interface SmsFeign {
    @GetMapping(value = "/alisendmessage")
    Integer smdAlisendmessage(@RequestParam("phone") String phone, @RequestParam("templateCode") String templateCode, @RequestParam("param") String param);

由上面的介绍可知,feign调用到的接口为server model中的这个接口

    /**
     * 阿里云短信服务
     *
     * @param phone        手机号
     * @param templateCode 模板编码-阿里云获取
     * @param param        参数Json,例如URLEncoder.encode("{\"code\":\"1234\"}","utf-8");
     * @return 0 成功 1 失败
     */
    //发短信-阿里云
    @GetMapping(value = "alisendmessage")
    public Integer aliSendmessage(String phone, String templateCode, String param) {
        log.info("phone+TemplateCode+TemplateCode:{}", phone + templateCode + param);
        return smsBiz.aliSendmessage(phone, templateCode, param);
    }

这样在B服务中定义的接口可以在B服务中可以调通。
接下来看A服务调用B能不能实现
将Bdeploy到私服的jar,引入到A服务中。
然后@Resource到一个Adapter中
将该接口的返回结果直接返回
然后@Autowired到控制器直接使用Adapter中的方法,拿到Feign的返回接口,然后就不用在控制器层或者逻辑层去解析Code message data那些罗里吧嗦了东西了

@Service
@Slf4j
public class CommonAdapter {
    @Resource
    private SmsFeign smsFeign;
    public Integer smdAlisendmessage(String phone, String templateCode, String param) {
        Integer result = null;
        try {
            result = smsFeign.smdAlisendmessage(phone,templateCode,param);
            if (result == null || Objects.equals(result, 1)) {
                throw new UserException(1 + "", "短信失败");
            }
            return result;
        } catch (UserException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }
    }

}

这里补充一个内容
Feign一般用在微服务之前的调用,那微服务之间的调用就会有access_token问题
需要加一个Configuration,附上url和header分别加token的代码

/**
 * Feign调用添加token
 */
@Configuration
public class FeignRequestConfig implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        System.out.println(request.getParameter("access_token"));
        System.out.println(request.getHeader("Access-Token"));
        // url添加token
        //noinspection AliDeprecation
        template.append("?access_token=" + request.getParameter("access_token"));
        // header添加token
        template.header("Access-Token", request.getHeader("Access-Token"));
    }
}

调用成功
完结 撒花

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值