spring cloud feign 坑

feign是啥?

很多人可能对于feign 不是很熟悉,可以看一下其他网友的实例分享:spring cloud feign简介

如果觉得上面这个比较难的话,还有一个简单入门的:spring cploud feign使用详解

今天的主题是记录遇到的坑,关于feign的资料网友分享已经很详细,我就不班门弄斧啦啦

feign 坑之@RequestParam参数名

这次在做一个中台项目(使用 spring boot),需要和市场上很多同行公司结合的那种,这就涉及到同个服务需要被很多外部服务调用的场景,之前通常都会用代理去实现对其他外部服务的访问,但代理模块也需要写很多代码,对于懒惰的程序员而言,这当然是要想办法简化的(是谁说的,不会偷懒的程序员都不是好程序员来着?)

然后有大神推荐我们使用了feign,Feign 是 Spring Cloud的组件,这里就需要讨论spring boot 和spring cloud 整合的问题了,但是不展开,可以移步扩展阅读。

在依赖了 spring cloud之后,外部服务就可以愉快的开始使用 feign来调用我们的接口了

@FeignClient(name = "${test-service.application.name}", configuration = TestServiceFeignConfig.class)
public interface TestServiceInterfaceClient extends TestServiceInterfaceApi{
}
TestServiceInterfaceApi 是我们中台内部实现的接口,接口定义如下:
/**
 * 版权所有(C),xxxx公司,2019,所有权利保留。
 * 
 * 项目名:    test-client-api
 * 文件名:    TestServiceApi.java
 * 模块说明:    
 * 修改历史:
 * 2019年6月20日 -ln- 创建。
 */
package com.xxxx.test.client.api.test;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * xxxxx服务
 * 
 * @author ln
 *
 */
@Api(tags = "xxxxx服务")
@RequestMapping(value = "service/test",
    produces = "application/json;charset=utf-8")
public interface TestServiceInterfaceApi {

  /**
   * 查询
   * 
   * @param id1
   *          id1
   * @param filter
   *          查询条件
   * @return 查询结果
   */
  @ApiOperation(value = "查询")
  @RequestMapping(value = "/query", method = RequestMethod.POST)
  @ResponseBody
  Response<List<TestEntity>> query( //
      @ApiParam(required = true) @PathVariable("id1") String id1,
      @ApiParam(required = true) @RequestBody TestFilter filter);

  /**
   * 批量移除
   * 
   * @param id1
   *          id1
   * @param modifition
   *          处理内容
   * @return 处理结果
   */
  @ApiOperation(value = " 批量移除")
  @RequestMapping(value = "/batchremove", method = RequestMethod.POST)
  @ResponseBody
  Response batchRemove( //
      @ApiParam(required = true) @PathVariable("id1") String id1,
      @ApiParam(required = true) @RequestBody TestBatchRemove batchRemove,
      @ApiParam(required = true) @RequestParam String operator);
}

这时候,在外部系统服务里 @Autowired 一下 TestServiceInterfaceClient 就可以调用到我们的接口了,按道理讲这个流程应该顺畅无比,毕竟定义 feignClient 才这么几行代码,不可能出错,but 程序员不可能是不写bug 的~~

外部服务启动时,报错:

这个报错是说我们中台服务的某个接口的第2 个参数为空,但是我们本地的服务是正常启用的,内部调用无比顺畅,那,问题在哪?

经过排查,发现是我们接口定义用到了 @RequestParam 注解,但是Feign 对 @RequestParam 声明的参数未识别到,加上参数的名字之后,一切OK

/**
   * 批量移除
   * 
   * @param id1
   *          id1
   * @param modifition
   *          处理内容
   * @return 处理结果
   */
  @ApiOperation(value = " 批量移除")
  @RequestMapping(value = "/batchremove", method = RequestMethod.POST)
  @ResponseBody
  Response batchRemove( //
      @ApiParam(required = true) @PathVariable("id1") String id1,
      @ApiParam(required = true) @RequestBody TestBatchRemove batchRemove,
      @ApiParam(required = true) @RequestParam("operator") String operator);
}

后面找了找,发现前面也有很多人遇到了相似的问题,还有网友系统的整理了坑,具体可异步扩展阅读。

虽然这是一个很小的点,小菜依旧很开心(毕竟不用背锅啊)。

我们的中台功能在不断地发展全面,so这篇帖子将会不断更新....

扩展阅读

原文地址:https://www.cnblogs.com/lilala-world/p/11060467.html