Feign 使用这几天遇到的一些问题

事情的起因要从我打算调用下paas模块服务开始
Feign 现在教程很多,然后引入下pom

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

自己定义下接口

@FeignClient(name = "weixinTokenClient", url = "https://qyapi.weixin.qq.com/cgi-bin")
public interface IWeiXinTokenClient {

   /**
    * 获取应用的token
    * @param corpid
    * @param corpsecret
    * @return
    */
   @RequestMapping(value = "/gettoken", method = RequestMethod.GET)
   WeiXinTokenResultModel getToken(@RequestParam String corpid, @RequestParam String corpsecret);
}

写个test类测试下,完美返回,因为自己写过类似的项目,可以看下lemur-http,原理大体一致,想了想还是简单的.但是后面的问题就出来
1. nacos 配置拿不到服务
原因是:nacos注册服务只注册了lemur-admin和lemur-paas这种服务级别的服务,获取服务地址需要用lemur-admin服务,但是在admin调用paas接口的时候

@FeignClient(value = "paasUserFacade", contextId = "lemur-paas", path = "/im/user")
public interface IPaasUserFacade extends IBaseController<PaasUserRequestModel> {

}

@FeignClient注解不论是value,name,contextId ,serviceId全都是当做了name,所以在获取nacos地址的地方都是用paasUserFacade去匹配的,根本无法拿到,最终一直跟了N遍代码,也没有找打解决办法,自己还是改了源码FeignClientFactoryBean,在注册bean的地方还是使用value ,并且不用contextId 注册别名,意义不大,还重名,把contextId 当做服务Id,feign是通过target来做地址解析的,所以只要把target的url地址改为lemur-paas/im/user就可以了

<T> T getTarget() {
		FeignContext context = this.applicationContext.getBean(FeignContext.class);
		Feign.Builder builder = feign(context);

		if (!StringUtils.hasText(this.url)) {
			if (StringUtils.hasText(this.contextId) && !this.name.startsWith("http")){
				this.url =  "http://" + this.contextId;
			}else if (StringUtils.hasText(this.contextId)){
				this.url =  this.contextId;
			} else if (!this.name.startsWith("http")) {
				this.url = "http://" + this.name;
			}
			else {
				this.url = this.name;
			}
			this.url += cleanPath();
			return (T) loadBalance(builder, context,
					new HardCodedTarget<>(this.type, this.name, this.url));
		}
		if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
			this.url = "http://" + this.url;
		}
		String url = this.url + cleanPath();
		Client client = getOptional(context, Client.class);
		if (client != null) {
			if (client instanceof LoadBalancerFeignClient) {
				// not load balancing because we have a url,
				// but ribbon is on the classpath, so unwrap
				client = ((LoadBalancerFeignClient) client).getDelegate();
			}
			builder.client(client);
		}
		Targeter targeter = get(context, Targeter.class);
		return (T) targeter.target(this, builder, context,
				new HardCodedTarget<>(this.type, this.name, url));
	}

改完源码之后,算是可以互相调用了
2.fastjson 不支持abstract class ,关键是不报错,直接返回null
因为风铃统一返回的都是Response对象,加泛型,结果怎么调用返回的都是null,看看被调用的服务是有收到请求并返回的,这个只能是客户端的问题了,一开始以为是泛型解析的问题,跟踪了整个调用解析链条

ReflectiveFeign.invoke->
SynchronousMethodHandler.invoke->
executeAndDecode->decode(解析对象)->
ResponseEntityDecoder.decode->
SpringDecoder.decode->
HttpMessageConverterExtractor.extractData(返回泛型)->
FastJsonHttpMessageConverter(真正的解析器).read(type,clazz,inputMessage)->
parseObject(is)

然后发现什么,fastjson无法实例化对象,我去你也报个错啊,把abstract去掉,就正常返回了

3.spring gateway 不支持web
spring gateway 因为使用webflux写的,不是web容器所以不能引入web,在引入feign的时候要把web去掉,不然起不来

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

同时spring gateway 也不支持读取配置文件,同理原因,像j2cache的文件配置方式就读取不到

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值