信息发布→ 登录 注册 退出

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

发布时间:2026-01-11

点击量:
目录
  • @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调用传输的是集合对象的问题啦

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

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!