Feign客户端的定义和注入使用及注意事项
业务场景:
用户服务customer调用订单服务order。
解决问题:
Feign客户端的定义,Feign客户端的注入使用。
一、Feign客户端的定义及项目模块划分
order项目分模块,在order-dto中定义Feign客户端接口。
dto中同时定义入参Req和出参DTO,便于其他模块中的微服务最小化最精简引入依赖。
注意:接口参数中都添加上各自注解,否则会产生文末的异常。
package com.szh.order.api;
@FeignClient(value = OrderApi.SERVICE_NAME)
public interface OrderApi {
final String SERVICE_NAME = "order";
@RequestMapping(path = "/order/save", method = RequestMethod.POST)
ApiResponse<OrderBaseDTO> saveOrder(@RequestBody SaveOrderReq req);
@RequestMapping(path = "/order/info", method = RequestMethod.GET)
ApiResponse<List<OrderDTO>> getOrder(@RequestParam("customer_name") String customerName,
@RequestParam("customer_phone") String customerPhone);
}
order-web中的Controller实现自身服务的FeignApi接口。
package com.szh.order.ctrl;
@RestController
public class OrderCtrl implements OrderApi {
@Override
public ApiResponse<OrderBaseDTO> saveOrder(@Validated @RequestBody SaveOrderReq req) {
// TODO
return ApiResponse.success(null);
}
@Override
public ApiResponse<List<OrderDTO>> getOrder(@RequestParam("customer_name") String customerName,
@RequestParam("customer_phone") String customerPhone) {
// TODO
return ApiResponse.success(null);
}
}
二、其他微服务注入Feign调用
customer引入order-dto的pom后注入。
package com.szh.customer.service;
import com.szh.order.api.OrderApi;
@Service
@Slf4j
public class CustomerServiceImpl implements CustomerService {
@Autowired
private OrderApi orderApi;
@Override
public UserOrderDTO getMyOrder(String userName, String userPhone) {
ApiResponse<List<OrderDTO>> resp = orderApi.getOrder(userName, userPhone);
log.info("用户相关的订单信息: {}", JSON.toJSONString(resp));
// TODO
return null;
}
}
注意点1
Field orderApi in com.szh.customer.service.CustomerServiceImpl required a bean of type 'com.szh.order.api.OrderApi' that could not be found.
原因:
未扫描到引入的Feign客户端。
解决方法:
用户服务主类指定Feign扫描包需包含order-dto。
@EnableFeignClients({ "com.szh.*.api"})
注意点2
java.lang.IllegalStateException: Method has too many Body parameters
原因:
多个接口参数下,未添加各自注解。
package com.szh.order.api;
@FeignClient(value = OrderApi.SERVICE_NAME)
public interface OrderApi {
final String SERVICE_NAME = "order";
@RequestMapping(path = "/order/save", method = RequestMethod.POST)
ApiResponse<OrderBaseDTO> saveOrder(SaveOrderReq req);
@RequestMapping(path = "/order/info", method = RequestMethod.GET)
ApiResponse<List<OrderDTO>> getOrder(String customerName, String customerPhone);
}
解决方法:
Feign客户端接口参数都最好添加上各自注解,如@RequestParam、@RequestHeader、@PathVariable、@RequestBody等。
还没有评论,来说两句吧...