这是在使用Feign优化Http调用时遇到的一个错误,启动时报错类似下方:
Ambiguous mapping. Cannot map ‘XXX’ method YYY to {GET /file/xxxx}: There is already ‘XXX’ bean method YYY mapped
首先在对应的Interface上添加了FeignClient注解,然后在启动类上添加了@EnableFeignClients({“com.xxx.xxx”})来扫描feign客户端
@RequestMapping("/file")
@FeignClient(value = SERVICE_FILE)
public interface FileUploadControllerApi {
@PostMapping("/uploadImg")
JsonResultObject uploadImg(@RequestParam String userId,@RequestParam MultipartFile file);
@PostMapping("/uploadToFS")
JsonResultObject uploadToFS(@RequestBody AdminBO adminBO);
……
}
这里最优先考虑的是:方法有没有重复映射,有没有重复的Mapping或者在实现的时候是否重复添加了mapping注解。
但是我遇到的情况是,没有找到任何重名映射,并且无论如何修改方法的映射路径,都会这个报错。而移除interface上的FeignClient注解,问题就消失了。其实原因是在这里:
// path:"org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java"
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
这里存在Controller注解或RequestMapping注解,就会被判定位isHandler,所以在interface上同时标注RequestMapping和FeignClient时,由于RequestMapping已经触发了一次装配,解析了路径,再遇到FeignClient时又需要解析路径,自然就发生了冲突(这里是我的理解,也许表达不是那么准确)。
因此,最简单的解法是不同时在这里使用这两个注解,将映射路径的公共部分也放到方法上面:
//@RequestMapping("/file")
@FeignClient(value = SERVICE_FILE)
public interface FileUploadControllerApi {
@PostMapping("/file/uploadImg")
JsonResultObject uploadImg(@RequestParam String userId,@RequestParam MultipartFile file);
@PostMapping("/file/uploadToFS")
JsonResultObject uploadToFS(@RequestBody AdminBO adminBO);
……
}
其他参考: