feign不支持get请求参数对象解决方案

1. 问题描述:早期controller有一个由前端直接调用的获取商品详情的接口getGoodsInfo(ReqGoodsInfo req), Get请求方式;

后来想要在业务服务由后台对商品详情页的几个接口整合成一个,那么前端直接只调用一次即可。选择了feign昨晚跨服务调用的调用框架。那么原先的getGoodsInfo接口就要提供一个可供调用的client端如下

@RequestMapping(
    method = RequestMethod.GET,
    value = "/goods/***/goodsInfo",
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
ResultInfo<RespUsersideGoodsInfo> getUsersideGoodsInfo(@RequestParam("req") ReqGoodsInfo req);

很遗憾,feign并不支持get请求参数对象,feign在底层会直接将get的请求方式转为post请求。

private synchronized OutputStream getOutputStream0() throws IOException {
    try {
      if (!this.doOutput) {
        throw new ProtocolException("cannot write to a URLConnection if doOutput=false - call setDoOutput(true)");
      } else {
        if (this.method.equals("GET")) {
          this.method = "POST";
        }
      }
    }
  }

2. 既然如此,那么有些人直接在feignClient端直接加@RequestBody注解,但是那样的话,controller层也需要使用@RequestBody注解,这违反HTTP协议;而且这种方式也不适用我的需要。

3. 那么就想到,controller使用对象接收的get入参,实际上也是各个参数url上的拼接。那么就可以在feignClient端的方法改为

@RequestMapping(
    method = RequestMethod.GET,
    value = "/goods/***/goodsInfo",
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
ResultInfo<RespUsersideGoodsInfo> getUsersideGoodsInfo(@RequestParam("goodsId") Long goodsId, @RequestParam("productId") Long productId);

注意:这里的@RequestParam每一项的value都要与controller参数名保持一致,否则无法接收值。

4. 但是,如果是对于入参个数比较多,甚至是嵌套对象等等复杂情况,以上3也是不好处理。

有推荐使用@SpringQueryMap注解的,但是spring版本需要2.1以上才支持;

经验分享 程序员 微信小程序 职场和发展