iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Feign远程调用传递对象参数并返回自定义分页数据的方法
  • 768
分享到

Feign远程调用传递对象参数并返回自定义分页数据的方法

2023-06-29 13:06:18 768人浏览 独家记忆
摘要

这篇文章主要介绍“Feign远程调用传递对象参数并返回自定义分页数据的方法”,在日常操作中,相信很多人在Feign远程调用传递对象参数并返回自定义分页数据的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”F

这篇文章主要介绍“Feign远程调用传递对象参数并返回自定义分页数据的方法”,在日常操作中,相信很多人在Feign远程调用传递对象参数并返回自定义分页数据的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Feign远程调用传递对象参数并返回自定义分页数据的方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Feign介绍

Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。spring cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。

Feign测试

1.在yml文件里面增加了配置信息

feign:  httpclient:    enabled: true

2.在客户端pom.xml文件中引入的依赖(消费者端)

<!-- 配置feign 发送请求使用 httpclient,而不是java原生 -->        <dependency>            <groupId>org.apache.httpcomponents</groupId>            <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>-->

但是不知道哪里的问题,在获取返回结果时一直报错:

Caused by: java.lang.NoSuchMethodError: feign.Response.create(ILjava/lang/String;Ljava/util/Map;Lfeign/Response$Body;)Lfeign/Response;

查看源码得知,openfeign在接受返回值时调用的不是httpclient的feign-core包的代码而是调用的本身的feign-core的代码,而本身的feign-core包中的Response类没有create方法。两个feign-core包中的Retryer接口不一致导致的,openfeign的feign-core版本为10.1.0 httpclient的版本为8.16.1。

找了半天问题,最后就把httpclient的依赖换成代码块中的依赖就OK了。

3.服务调用端接口为

此处使用POST请求,第6步有解释。

@Slf4j@RequestMapping("/list")@RestControllerpublic class WEBQueryListController {           @Autowired    private TourismListService listService;       @PostMapping("/ad/allByQuery")    public apiResult<Page<TourismAd>> allByQuery(@RequestBody TourismAdQuery adQuery){        ApiResult<Page<TourismAd>>  pageApiResult =  listService.selectAllAdByQuery(adQuery);        return pageApiResult;    }

我的TourismAdQuery类继承了Page类(似乎没有影响)

@Datapublic class TourismAdQuery extends  Page<TourismAd> {         private String title;     。。。。。。。}

4.服务调用端Service代码

此处@PostMapping地址为服务端提供的api接口地址

@FeignClient(name = "fisher-back-service", fallback = TourismListFallback.class, configuration = FeignConfig.class)public interface TourismListService {        @PostMapping(value = "/ad/get/allByQuery")    ApiResult<Page<TourismAd>> selectAllAdByQuery(TourismAdQuery adQuery);

5.服务调用端Fallback为

@Slf4j@Servicepublic class TourismListFallback implements TourismListService {         @Override    public ApiResult<Page<TourismAd>> selectAllAdByQuery(TourismAdQuery adQuery) {        log.error("调用 selectAllAdByQuery 方法异常,参数:{}", adQuery);        return null;    }

6.服务提供端代码为

此处传进来的参数是一个POJO类,如果不使用@RequestBody注解 的话,feign远程调用时参数是无法被接收到的。

虽然获取数据时,大多数使用 Get请求方法,但是GET方法无法接收@RequestBody参数体。

所以只好改GET请求为POST请求。

@RestController@RequestMapping("/ad")public class TourismAdController extends BaseController<TourismAdService, TourismAd, Integer> {     @Autowired    private TourismAdService adService;    @ApiOperation(value = "分页查询广告根据查询条件", notes = "分页查询广告根据查询条件", httpMethod = "POST")    @PostMapping("/get/allByQuery")    public ApiResult<Page<TourismAd>> allByQuery(@RequestBody TourismAdQuery adQuery){        return adService.selectAllByQuery(adQuery);    }

7.测试

调用接口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",        "leaseperson": "找找",        "address": "杭州市",        "idcard": "1154465656656",        "phone": "131654799"      }    ],    "total": 1,    "size": 6,    "current": 1,    "searchCount": true,    "pages": 1  },  "code": 200,  "message": "分页获取成功"}

Feign调用分页接口报错:Method has too many Body parameters

接口定义:

@ApiOperation(value = "分页查询会话")@PostMapping(Routes.SESSIONS_QUERY)jsonResult<Pagination<SessionInfo>> querySessions(@RequestBody @Valid SessionsQo 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.ISessionController.querySessions(com.xingren.xxx.yyy.contract.qo.SessionsQo,org.springframework.data.domain.Pageable)

解决方法

通过搜索、调研,目前有三种解决方法:

1、将分页属性直接通过入参传递,接口定义如下:

@ApiOperation(value = "分页查询会话")@PostMapping(Routes.SESSIONS_QUERY)JsonResult<Pagination<SessionInfo>> querySessions(@RequestBody @Valid SessionsQo qo,@RequestParam("page") Integer page, @RequestParam("size") Integer size, @RequestParam("sort") Sort sort);

2、将分页对象冗余在Qo中(通过继承实现):

@Data@NoArgsConstructor@ApiModel(value = "查询会话")public class SessionsQo extends PageableParam {@ApiParam(value = "会话id列表")private List<Long> sessionIdIn = Lists.newArrayList();...}

3、通过注解传递(参考:Issue):

服务提供方定义注解:

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface PageableParam {}

服务提供方定义接口:

@ApiOperation(value = "分页查询会话")@PostMapping(Routes.SESSIONS_QUERY)JsonResult<Pagination<SessionInfo>> querySessions(@RequestBody @Valid SessionsQo 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对QueryMap类型参数的序列化和反序列化的言七墨方式与Sort.Order的不兼容,导致排序失效。

服务消费方调用方式:

SessionsQo qo = SessionsQo.builder().sessionIdIn(Collections.singletonList(20L)).build();JsonResult<Pagination<SessionInfo>> pageInfo = sessionContract.querySessions(qo, new PageableUtil(0, 5, new Sort(Sort.Direction.DESC,

到此,关于“Feign远程调用传递对象参数并返回自定义分页数据的方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Feign远程调用传递对象参数并返回自定义分页数据的方法

本文链接: https://www.lsjlt.com/news/325018.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作