记录使用Fegin时遇到的BUG:
BUG场景:
在微服务项目中,有需要上传文件作为参数的接口,在接口的实现中用到了Fegin去调用其他服务的接口,会出现Fegin无法调通接口的问题。
问题描述
在Controller类的接口入口处,添加MultipartFile 作为参数类型,在接口的Service层实现代码中,通过Fegin调用其他服务接口,出现fegin无法调通的问题
Controller类实现
@Resource
TestService testService;
@PostMapping("testUploadFile")
public Result testUploadFile(@RequestParam("file") MultipartFile file) throws Exception{
testService.testFegin(file,"这是一个id");
return null;
}
Service类实现
@Resource
TestFeignService testFeignService;
public void testFegin(MultipartFile file , String id){
doSomething(file);
Result result = testFeignService.testFegin(id);
}
FeginClient类实现
@FeignClient(value = "test",fallbackFactory = TestFallBackFactory.class)
public interface TestFeignService {
@GetMapping(value = "/testtt")
Result testFegin(@RequestParam String id);
}
被Fegin调用类实现
@GetMapping(value = "/testtt")
@ResponseBody
public Result testtt( @RequestParam String id) throws Exception {
return ResultUtil.success(doSomething(id));
}
原因分析:
经过对比,发现当Controller不以MultipartFile 作为参数类型时,可以正常调用Fegin服务,定位问题与MultipartFile 有关。分析由于传输文件作为参数时,会影响请求的Content-Type,用feign接着调用其他服务接口时,由于被调用的接口不支持请求的Content-Type为multipart/form-data,导致调用失败。
解决方案:
手动限制Fegin调用接口时请求的Content-Type,在接口注解中用consumes属性指定需要的Content-Type类型
修改后的FeginClient类实现
@FeignClient(value = "test",fallbackFactory = TestFallBackFactory.class)
public interface TestFeignService {
@GetMapping(value = "/testtt",consumes = MediaType.APPLICATION_JSON_VALUE)
Result testFegin(@RequestParam String id);
}
手动指定Content-Type之后,fegin服务去调用其他服务接口时,不会再以multipart/form-data作为请求类型,而是以被调用接口可以支持的的"application/json"作为请求类型,可以正常用fegin调用其他服务接口。