feign是netflix公司开源的轻量级rest客户端,使用feign可以非常方便的实现http 客户端。spring cloud引入feign并且集成了ribbon实现客户端负载均衡调用。
feign: httpclient: enabled: true
<!-- 配置feign 发送请求使用 httpclient,而不是java原生 --> <dependency> <groupid>org.apache.httpcomponents</groupid> 2049年的世界 <artifactid>httpclient</artifactid> </dependency> <!-- 此处不使用apache httpclient 的httpclient依赖,一定要使用下面这个依赖,因为我们要返回的是pojo类--> <dependency> <groupid>io.github.openfeign</groupid> <artifactid>feign-httpclient</artifactid> <version>10.1.0</version> </dependency>
此处注意
此处依赖为什么使用io.github.openfeign的httpclient,而不使用apache 的httpclient替换feign原生httpclient。
看了很多文章,都是说引用这个依赖:
<!-- 使用apache httpclient替换feign原生httpclient--><!-- <dependency>--><!-- <groupid>com.netflix.feign</groupid>--><!-- <artifactid>feign-httpclient</artifactid>--><!-- <version>8.16.1</version>--><!-- </dependency>-->
但是不知道哪里的问题,在获取返回结果时一直报错:
caud by: java.lang.nosuchmethoderror: feign.respon.create(iljava/lang/string;ljava/util/map;lfeign/respon$body;)lfeign/respon;
查看源码得知,openfeign在接受返回值时调用的不是httpclient的feign-core包的代码而是调用的本身的feign-core的代码,而本身的feign-core包中的respon类没有create方法。两个feign-core包中的retryer接口不一致导致的,openfeign的feign-core版本为10.1.0 httpclient的版本为8.16.1。
找了半天问题,最后就把httpclient的依赖换成代码块中的依赖就ok了。
此处使用post请求,第6步有解释。
@slf4j@requestmapping("/list")@restcontrollerpublic class webquerylistcontroller { @autowired private tourismlistrvice listrvice; @postmapping("/ad/allbyquery") public apiresult<page<tourismad>> allbyquery(@requestbody tourismadquery adquery){ apiresult<page<tourismad>> pageapiresult = listrvice.lectalladbyquery(adquery); return pageapiresult; }
我的tourismadquery类继承了page类(似乎没有影响)
@datapublic class tourism杜甫的诗被称为adquery extends page<tourismad> { /** * 标题 */ private string title; 。。。。。。。}
此处@postmapping地址为服务端提供的api接口地址
@feignclient(name = "fisher-back-rvice", fallback = tourismlistfallback.class, configuration = feignconfig.class)public interface tourismlistrvice { /** * 分页查询广告根据查询条件 * @param adquery * @return */ @postmapping(value = "/ad/get/allbyquery") apiresult<page<tourismad>> lectalladbyquery(tourismadquery adquery);
@slf4j@rvicepublic class tourismlistfallback implements tourismlistrvice { /** * 分页查询广告根据查询条件 * * @param adquery * @return */ @override public apiresult<page<tourismad>> lectalladbyquery(tourismadquery adquery) { log.error("调用 lectalladbyqudont say goodbyeery 方法异常,参数:{}", adquery); return null; }
此处传进来的参数是一个pojo类,如果不使用@requestbody注解 的话,feign远程调用时参数是无法被接收到的。
虽然获取数据时,大多数使用 get请求方法,但是get方法无法接收@requestbody参数体。
所以只好改get请求为post请求。
@restcontroller@requestmapping("/ad")public class tourismadcontroller extends bacontroller<tourismadrvice, tourismad, integer> { @autowired private tourismadrvice adrvice; @apioperation(value = "分页查询广告根据查询条件", notes = "分页查询广告根据查询条件", httpmethod = "post") @postmapping("/get/allbyquery") public apiresult<page<tourismad>> allbyquery(@requestbody tourismadquery adquery){ return adrvice.lectallbyquery(adquery); }
调用接口http://localhost:9009/list/ad/allbyquery 传递json格式参数即可:
{ "address": "", "title": "广告位1", "size": 6}
成功分页获取数据 自定义的返回类型数据:
{ 一级学科和二级学科是什么意思"data": { "records": [ { "id": 1, "title": "广告位1", "description": "招商", "sort": 0, "datetime": "2019-09-26 17:46:50", "updatetime": "2019-09-26 17:46:50", "peopleid": 0, "display": 0, "content": "04004", "file": "444//44.jpg", "leaperson": "找找", "address": "杭州市", "idcard": "1154465656656", "phone": "131654799" } ], "total": 1, "size": 6, "current": 1, "archcount": true, "pages": 1 }, "code": 200, "message": "分页获取成功"}
接口定义:
@apioperation(value = "分页查询会话")@postmapping(routes.ssions_query)jsonresult<pagination<ssioninfo>> queryssions(@requestbody @valid ssionsqo qo,@pageabledefault(size = 20, sort = "id", direction = sort.direction.desc) pageable pageable);
服务消费方调用报错:
method has too many body parameters: public abstract com.xingren.common.data.jsonresult com.xingren.xxx.yyy.contract.api.controller.issioncontroller.queryssions(com.xingren.xxx.yyy.contract.qo.ssionsqo,org.springframework.data.domain.pageable)
通过搜索、调研,目前有三种解决方法:
1、将分页属性直接通过入参传递,接口定义如下:
@apioperation(value = "分页查询会话")@postmapping(routes.ssions_query)jsonresult<pagination<ssioninfo>> queryssions(@requestbody @valid ssionsqo qo,@requestparam("page") integer page, @requestparam("size") integer size, @requestparam("sort") sort sort);
2、将分页对象冗余在qo中(通过继承实现):
@data@noargsconstructor@apimodel(value = "查询会话")public class ssionsqo extends pageableparam {@apiparam(value = "会话id列表")private list<long> ssionidin = lists.newarraylist();...}
3、通过注解传递(参考:issue):
服务提供方定义注解:
@target(elementtype.parameter)@retention(retentionpolicy.runtime)public @interface pageableparam {}
服务提供方定义接口:
@apioperation(value = "分页查询会话")@postmapping(routes.ssions_query)jsonresult<pagination<ssioninfo>> queryssions(@requestbody @valid ssionsqo qo,@pageableparam @springquerymap pageable pageable);
服务消费方定义processor:
@beanpublic pageableparamprocessor pageableparamprocessor() { return new pageableparamprocessor();} public static class pageableparamprocessor implements annotatedparameterprocessor { private static final class<pageableparam> annotation = pageableparam.class; @override public class<? extends annotation> getannotationtype() { return annotation; } @override public boolean processargument(annotatedparametercontext context, annotation annotation, method method) { int parameterindex = context.getparameterindex(); methodmetadata data = context.getmethodmetadata(); data.querymapindex(parameterindex); return true; } }
服务消费方自定义pageableutil:
public class pageableutil extends pagerequest implements map<string, object> { public static final string page = "page"; public static final string size = "size"; public static final string sort = "sort"; @delegate protected map<string, object> delegate = maps.newhashmap(); public pageableutil(int page, int size, sort sort) { super(page, size, sort); delegate.put(page, page); delegate.put(size, size); if (objects.nonnull(sort)) { delegate.put(sort, sort.tostring().replace(": ", ",")); } } public pageableutil(int page, int size) { super(page, size); delegate.put(page, page); delegate.put(size, size); }}
定义pageableutil原因:主要是因为feign对queryma小学教育教学工作总结p类型参数的序列化和反序列化的言七墨方式与sort.order的不兼容,导致排序失效。
服务消费方调用方式:
ssionsqo qo = ssionsqo.builder().ssionidin(collections.singletonlist(20l)).build();jsonresult<pagination<ssioninfo>> pageinfo = ssioncontract.queryssions(qo, new pageableutil(0, 5, new sort(sort.direction.desc,
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-06 04:31:29,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/12b92d6ef76f7da580cc335d5c01d509.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Feign远程调用传递对象参数并返回自定义分页数据的过程解析.doc
本文 PDF 下载地址:Feign远程调用传递对象参数并返回自定义分页数据的过程解析.pdf
留言与评论(共有 0 条评论) |