由之前的dubbo改用SpringCloud微服务之间通过FeignClient进行调用今天在测试的时候eureka注册中心有相应的服务但feignclient就是无法调通一直报404错误排查过程如下一、问题服务提供方定义的接口如下/** * 黑白名单查询接口 * * author LiJunJun * since 2018/10/18 */ Component(value blackAndWhiteListFeignClient) FeignClient(value pear-cache-service, path v1/cache/limitlist) public interface IBlackAndWhiteListFeignClient { /** * 获取黑白名单手机号分组编号 * * param trace 请求流水 * param phoneNum 电话号码 * return 电话号码所在分组 */ RequestMapping(value /blackAndWhiteList, method RequestMethod.POST, produces MediaType.APPLICATION_JSON_UTF8_VALUE) ResultDataString blackAndWhiteList(RequestHeader(name Trace) String trace, RequestParam(phoneNum) String phoneNum); }接口实现类如下/** * 黑白名单controller * * author LiJunJun * since 2018/10/18 */ ProtectedLdApi RestController RequestMapping(value v1/cache/limitlist) Api(value 黑白名单缓存, description 黑白名单缓存相关接口) public class BlacklAndWhiteListController extends AbstractController implements IBlackAndWhiteListFeignClient { /** * 日志记录器 */ private final static Log LOGGER new Log(BlacklAndWhiteListController.class); /** * 注入tedis */ Autowired private JedisSentinelPoolExt jedisSentinelPool; /** * 获取黑白名单手机号分组编号 * * param trace 请求流水 * param phoneNum 电话号码 * return 电话号码所在分组 */ Override ApiOperation(value 获取黑白名单手机号分组编号, notes 根据电话号码从缓存中获取黑白名单分组) RequestMapping(value /blackAndWhiteList, method RequestMethod.POST, consumes MediaType.APPLICATION_JSON_UTF8_VALUE, produces MediaType.APPLICATION_JSON_UTF8_VALUE) public ResultDataString blackAndWhiteList(RequestHeader(name Trace) String trace, RequestParam(phoneNum) String phoneNum) { do something... } }调用方如下public class MessageListController { private static final Log LOGGER new Log(MessageListController.class); Autowired private IBlackAndWhiteListFeignClient blackAndWhiteListFeignClient; RequestMapping(value /testBlackAndWhiteList, method RequestMethod.POST, produces MediaType.APPLICATION_JSON_UTF8_VALUE) public ResultDataString testBlackAndWhiteList() { LOGGER.info(开始调用缓存接口); ResultDataString res blackAndWhiteListFeignClient.blackAndWhiteList(asdqwezxxc, B18037903086); LOGGER.info(调用结果 res.getResultData()); return res; }调用结果华丽丽的404了很头疼经过各种度娘发现导致这个问题有两个原因以下是解决方法二、问题分析经过百度说将SpringBoot配置文件里面 server.servlet.context-path 注释掉即可抱着试一哈的态度注释了重启调用结果惊喜的发现依旧报错了但仔细一看错误代码已经不是404变成了415这就相当于调通了但是Content-Type的类型不对于是返回去看代码此时已经肯定今天能把feignclient接口调通仔细一看发现接口上定义的RequestMapping中只定义了 produces MediaType.APPLICATION_JSON_UTF8_VALUE而实现类中RequestMapping定义了consumes、produces均为 application/json;charsetUTF-8我们知道consumes定义了方法接受的Http的请求类型produces则定义了Http请求返回的类型然后我们说下FeignClient它的底层实现就是根据定义的FeignClient接口来组装Http请求进行远程调用而Http默认的Content-type是x-www-form-urlencoded类型化的到这儿问题就呼之欲出了再来回顾上面我们定义的接口并没有指定请求类型consumes那么FeignClient组装的Http请求的类型就是默认的x-www-form-urlencoded类型但我们的实现类上却定义了consumesMediaType.APPLICATION_JSON_UTF8_VALUE也就是说仅接受json类型的请求这就是为什么415的原因了三、解决方法知道了问题的原因解决起来就很简单了我们可以在FeignClient的接口定义上指定consumes这样FeignClient在组装Http请求的时候就会在header里面设置请求类型为application/json这样问题就完美解决再来看调用结果完美返回四、总结feignclient接口定义是一个模板化的其组装的Http请求完全按照你定义的接口去组装如你在参数中用RequestHeader去接收一个参数其组装请求时就会将你传入的参数放至Header中你指定的consumes为json其组装的请求Content-Type就是 application/json类型的完全不需要调用方感知就像调用普通方法一样不得不说很强大只要生成的Http请求正确服务提供方提供的Rest接口能和FeignClient组装的Http请求就能够完成远程调用。