Feign接口方法返回值设置方式

网友投稿 2753 2022-12-29

Feign接口方法返回值设置方式

Feign接口方法返回值设置方式

一、介绍

随着微服务的广泛应用,越来越多的企业都会使用微服务进行项目开发,在各个服务之间需要通过feign来进行通信,所以在feign调用接口中方法会接受其他服务接口不同类型返回值。

二、返回值设置

1、依据被调用服务接口设置相同返回类型

介绍:微服务A接口getUser 返回List类型,微服务B通过feign调用方法也返回相同的结果类型。

特点:返回类型一一对应,在调用时不需要进行转化直接拿来就可以用。

缺点:扩展性不好,维护性不加。

解释:在目前springboot开发中,接口一般都会返回json类型数据(也就是使用@restController或者使用@ResponseBody注解修饰),就算是对象或者对象集合也是一样的,或者其他自己封装的返回对象。如果有许多不同的返回对象,当这些返回对象在A服务做了修改相应的在B服务的feign接口处也要做修改,相当麻烦且不符合java面向接口编程思想。

2、全部设置为String

介绍:微服务A接口只要被@restController或者使用@ResponseBody注解修饰我统统在微服务Bfeign接口使用String来进行接受。

特点:通过String来接受返回参数,格式一致。http://

缺点:后面调用需要转换。

代码介绍:

// 微服务A controller 已经使用@restController修饰

@PostMapping(value="/getAllQuestionBank",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)

public List getAllQuestionBank(){

return baseinfoQuestionMange.getAllQuestionBank();

}

// 微服务B feign接口 使用String进行接受

@PostMapping(value="/baseinfo/getAllQuestionBank")

String getAllQuestionBank();

// 微服务B 当需要调用feign信息时需要强转成List格式

// 调用微服务获取题库章节信息,该处强制使用try catch进行包裹

String questionBankInfo = baseInfoApi.getAllQuestionBank();

List mysqlQuestionBank = objectMapper.readValue(questionBankInfo,new TypeReference>(){});

只要你导入一下springboot依赖,它默认就给你导入了Jackson jar包

注意事项:使用该方式时需要将ObjectMapper配置到bean容器中。

3、总结

项目不同,需求不同,两种方式没有谁对谁错之分,依据自己项目需求进行选择。

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

事情的起因要从我打算调用下paas模块服务开始

Feign 现在教程很多,然后引入下pom

org.springframework.cloud

spring-cloud-starter-openfeign

自己定义下接口

@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 {

}

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

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去掉,不然起不来

org.springframework.cloud

spring-cloud-starter-openfeign

spring-boot-starter-web

org.springframework.boot

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:综合窗口企业开办一网通办(企业开办一网通办办理)
下一篇:小程序组件 水平排列(小程序排序界面)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~