SpringCloud版本:Greenwich.SR1
SpringBoot版本:2.1.5.RELEASE
最近在搞微服务架构的项目,想把系统核心模块的移动端接口单独汇总到移动端微服务中,自然就引入了Fegin,参考技术文档后觉得也挺简单的,在新的模块里使用@FeginClient注解类继承一下之前写好的接口就可以在微服务中调用了,但往往觉得简单的事却没有想象的简单,启动项目时,抛出了FeginClient注解类自动创建注入失败的异常,fegin类和异常如下图。
虽然报了错,但是却没有说具体哪里错了,因为我引用的接口是用依赖方式导入的不在启动目录下,如果想获取具体的报错内容,需要把feginclient注解类放在启动类的同级目录或子目录下。这样启动时就会抛出具体的问题所在了。
于是乎,发现启动时问题所在了......似乎是某个接口的参数问题。经过无数次的Debug之后,我发现fegin似乎对接口的规范相当严格,很多平时在spring boot里不注意的细节都有可能导致它注入异常。下面就总结下启动项目时的报错,和解决方式吧。
异常原因1:
接口的请求参数中包含@RequestBody注解,但又同时有多个参数的,就会抛出上图所示多参数异常,在接口代码如下。
@PostMapping("/export")
void export(@RequestBody @Valid RequestObject<ProductExportDto> requestObject,
@ApiIgnore HttpServletResponse response);
解决方法:有时接口有请求参数需要body的同时又会用到response或request,建议通过注入到类的方式调用。可以回避这个问题。
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@GetMapping(value = "")
public String center() {
//...
}
异常原因2:
请求参数中包含路径参数时,如果使用了@PathVariable注解,且使用默认值,则会抛出异常。
@PostMapping(value = "/list/{category}")
ResponseObject<List<ProductVo>> list(@PathVariable String category);
解决方式:给@PathVariable配置参数
@PostMapping(value = "/list/{category}")
ResponseObject<List<ProductVo>> list(@PathVariable(value = "category") String category);
异常原因3:
请求参数中如果使用了@RequestParam注解,且使用默认值,则会抛出异常。
@GetMapping(value = "/selectSnotiUseful")
ResponseObject<List<ProductVo>> selectSnotiUseful(@RequestParam Integer paasId);
解决方法:给@RequestParam 配置参数
@GetMapping(value = "/selectSnotiUseful")
ResponseObject<List<ProductVo>> selectSnotiUseful(@RequestParam(value = "paasId") Integer paasId);