springcloud feign调其他微服务时参数是对象的问题

目录
  • @RequestBody
  • GET请求多参数的URL
    • 正确写法如下
  • POST请求包含多个参数

在使用feign调用其它服务时,发现获取的参数是null,当参数是对象是,是执行的Post请求,所以要在方法参数前加@RequestBody,

@RequestBody

处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。

  • GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。
  • POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

GET请求多参数的URL

假设我们请求的URL包含多个参数,例如http://microservice-provider-user/get?id=1&username=张三 ,要怎么办呢?

我们知道Spring Cloud为Feign添加了Spring MVC的注解支持,那么我们不妨按照Spring MVC的写法尝试一下:

@FeignClient("microservice-provider-user")
public interface UserFeignClient {
  @RequestMapping(value = "/get", method = RequestMethod.GET)
  public User get0(User user);
}

然而我们测试时会发现该写法不正确,我们将会收到类似以下的异常:

feign.FeignException: status 405 reading UserFeignClient#get0(User); content:
{"timestamp":1482676142940,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/get"}

由异常可知,尽管指定了GET方法,Feign依然会发送POST请求。

正确写法如下

(1) 方法一

@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
  @RequestMapping(value = "/get", method = RequestMethod.GET)
  public User get1(@RequestParam("id") Long id, @RequestParam("username") String username);
}

这是最为直观的方式,URL有几个参数,Feign接口中的方法就有几个参数。使用@RequestParam注解指定请求的参数是什么。

(2) 方法二

@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
  @RequestMapping(value = "/get", method = RequestMethod.GET)
  public User get2(@RequestParam Map<String, Object> map);
}

多参数的URL也可以使用Map去构建。当目标URL参数非常多的时候,可使用这种方式简化Feign接口的编写。

POST请求包含多个参数

下面我们来讨论如何使用Feign构造包含多个参数的POST请求。举个例子,假设我们的用户微服务的Controller是这样编写的:

@RestController
public class UserController {
  @PostMapping("/post")
  public User post(@RequestBody User user) {
    ...
  }
}

我们的Feign接口要如何编写呢?答案非常简单,示例:

@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
  @RequestMapping(value = "/post", method = RequestMethod.POST)
  public User post(@RequestBody User user);
}

feign接口调用其他微服务中参数是集合对象(List<Java对象>)且请求方式是PUT或者POST方式的解决

首先,如果传输的是集合对象,一般的不是PUT或者POST请求都是可以用@RequestParam("…")的形式写在接口的新参中,比如

@GetMapping("/find/sec/consume/product/category")
public ResponseEntity<List<SecConsumeProductCategoryVO>> getSecConsumeProductCategory(@RequestParam("sellerIds") List<Long> sellerIds){
    List<SecConsumeProductCategoryVO> secConsumeProductCategories = secConsumeProductBaseBusinessService.getSecConsumeProductCategory(sellerIds);
    return ResponseEntity.ok(secConsumeProductCategories);
}

而对于feign调用且参数是集合对象的情况, 在feign客户端,则可以使用如下方式,请求路劲的注解就不能直接使用@PutMapping或者@PostMapping了,而必须使用@RequestMapping,形参仍然使用注解@RequestBody

@RequestMapping(value = "/cancel/daily/appointment",method = RequestMethod.PUT)
public Void updateBatchDailyAppointment(@RequestBody List<PdProductDailyAppointmentDTO> cancelAppointmentDTOS/*String cancelAppointmentStr*/);

而对于被调用方,则可以这样写

@RequestMapping(value = "/cancel/daily/appointment",method = RequestMethod.PUT)
public ResponseEntity<Void> updateBatchDailyAppointment(@RequestBody List<PdProductDailyAppointmentDTO> cancelAppointmentDTOS/*String cancelAppointmentStr*/){
    pdProductDailyAppointmentBusinessService.updateBatchDailyAppointment(cancelAppointmentDTOS);
    return ResponseEntity.status(HttpStatus.CREATED).build();
}

这样,就可以解决feign调用传输的是集合对象的问题啦

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Cloud中关于Feign的常见问题总结

    一.FeignClient接口,不能使用@GettingMapping 之类的组合注解 代码示例: @FeignClient("microservice-provider-user") public interface UserFeignClient { @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET) public User findById(@PathVariable(&quo

  • Spring Cloud Feign 使用对象参数的操作

    目录 概述 @RequestBody @SpringQueryMap QueryMapEncoder 解决方案 概述 Spring Cloud Feign 用于微服务的封装,通过接口代理的实现方式让微服务调用变得简单,让微服务的使用上如同本地服务.但是它在传参方面不是很完美.在使用 Feign 代理 GET 请求时,对于简单参数(基本类型.包装器.字符串)的使用上没有困难,但是在使用对象传参时却无法自动的将对象包含的字段解析出来. 如果你没耐心看完,直接跳到最后一个标题跟着操作就行了. @Req

  • SpringCloud Feign参数问题及解决方法

    这篇文章主要介绍了SpringCloud Feign参数问题及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天遇到使用Feign调用微服务,传递参数时遇到几个问题 1.无参数 以GET方式请求 服务提供者 @RequestMapping("/hello") public String Hello(){ return "hello,provider"; } 服务消费者 @GetMapping("

  • 解决SpringCloud Feign传对象参数调用失败的问题

    SpringCloud Feign传对象参数调用失败 不支持GET请求方式 使用Apache HttpClient替换Feign原生httpclient @RequestBody接收json参数 bootstrap-local.yml feign: httpclient: enabled: true pom.xml <!-- 使用Apache HttpClient替换Feign原生httpclient --> <dependency> <groupId>com.netf

  • springcloud feign调其他微服务时参数是对象的问题

    目录 @RequestBody GET请求多参数的URL 正确写法如下 POST请求包含多个参数 在使用feign调用其它服务时,发现获取的参数是null,当参数是对象是,是执行的Post请求,所以要在方法参数前加@RequestBody, @RequestBody 处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据. GET请求中,因为没有HttpEntity,所以@RequestB

  • springcloud使用feign调用服务时参数内容过大问题

    目录 feign调用服务时参数内容过大 场景 解决方法 feign消费时,如果传入参数过长 导致feign.FeignException: status 400 reading错误 解决办法 feign调用服务时参数内容过大 场景 前端参数传入到gateway后,gateway使用feign调用服务时,传入的参数内容过大(参数常见于富文本.或者其他附属信息过多)会导致传输不过去,虽然配置可以调节内容大小,但是最大的也有上限,所以特殊处理一道. 例如该类参数: 解决方法 可新增两个redis公共方

  • 浅谈SpringCloud实现简单的微服务架构

    Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路器.数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署.Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂.易部署和易维护的分布式系统开发工具包. 接下

  • SpringCloud超详细讲解微服务网关Zuul

    目录 网关的作用 Spring Cloud 网关组件Zuul介绍 Zuul网关实战 1.创建服务 2.创建配置文件 3.创建Zuul过滤器 4.编写启动类 5.启动验证 总结 网关的作用 微服务架构中,服务实例的地址可能经常会发生变化,所以我们不能直接将服务的地址暴露出来.如果每一个微服务都直接暴露接口,会导致一系列的问题,比如调用过于复杂,涉及到账户.权限不能统一处理等.另外基于高内聚低耦合的设计准则来讲,我们也应该将内部系统和外部系统做切割. 因此,这时就需要有一个独立的组件来处理外部的请求

  • SpringCloud超详细讲解微服务网关Gateway

    目录 前言 微服务网关GateWay介绍 GateWay特性介绍 Gateway 中的相关术语 Gateway实战 1.创建项目gateway 2.创建启动类 3.新增配置文件 4.编程方式实现路由 5.启动验证 总结 前言 上一篇:微服务网关Zuul 上文中,我们介绍了微服务网关Zuul,Zuul 是 Netflix 公司开源的产品,被称为第一代网关,也是 Spring Cloud 前几个版本默认使用的一款提供动态路由微服务网关组件,但是随着 Netflix 公司一系列的停更事件,在最新的 S

  • 通过FeignClient调用微服务提供的分页对象IPage报错的解决

    目录 问题描述 解决办法 feign返回IPage无法返回结果集 Mybatis-plus修改方式 feign的几种可能性 基于以上三点,有如下可能性 问题描述 通过FeignClient调用微服务提供的分页对象IPage报错 {"message": "Type definition error: [simple type, class com.baomidou.mybatisplus.core.metadata.IPage]; nested exception is com

  • springcloud使用Hystrix进行微服务降级管理

    前言:目前我们的项目是微服务架构,基于dubbo框架,服务之间的调用是通过rpc调用的.刚开始没有任何问题,项目运行健康.良好.可是过了一段时间,线上总有人反应查询订单失败,等过了一段时间才能查到.这是怎么回事呢?打开后台的日志一看出现了一些RpcException和TimeOutException,原来是远程调用超时了,可能某个服务在请求的高发期访问数据库异常,IO阻塞,返回接口异常了.后来这个问题越来越频繁,如何解决这个棘手的问题呢? 一:Hystrix是什么? 1.1:基本解释 Hystr

  • springcloud feign 接口指定接口服务ip方式

    目录 feign接口指定接口服务ip 场景 调用Feign接口时指定ip 只指定服务名 指定ip feign接口指定接口服务ip 场景 现在有2个服务,在eureka注册的服务名称一样,但是对外的接口不一样.其中有一方不允许合并代码,只能把另一个调用指定一下具体的服务地址 @FeignClient(name = "服务名称",url = "${url}",fallback = ServiceHystrix.class) public interface Servic

  • springcloud feign 接口指定接口服务ip方式

    目录 feign接口指定接口服务ip 场景 调用feign接口时指定ip 只指定服务名 指定ip feign接口指定接口服务ip 场景 现在有2个服务,在eureka注册的服务名称一样,但是对外的接口不一样.其中有一方不允许合并代码,只能把另一个调用指定一下具体的服务地址 @FeignClient(name = "服务名称",url = "${url}",fallback = ServiceHystrix.class) public interface Servic

  • SpringCloud Feign实现微服务之间相互请求问题

    目录 Feign简介 Spring Cloud 组件依赖版本 Feign实现服务之间访问 ☘创建nacos-consumer-feign微服务 创建feign client ☘nacos-provider微服务 Feign微服务之间访问测试 ☘Feign容错机制 上篇文章说了通过RestTemplate实现微服务之间访问:https://www.jb51.net/article/252981.htm,这篇文章将通过Feign实现微服务之间访问.代码基于RestTemplate实现微服务之间访问基

随机推荐