OpenFeign 实践通过 @SpringQueryMap 注解让Feign 接口中的 GET 请求支持 POJO 参数

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、问题描述:

一句话概括:我们的 FeignClient 接口在 GET 请求下支持 POJO 参数?

如果我们调用放的接口是一个 GET 请求,如果我们是用 @FeignClient 直接定义 POJO 参数如下代码:

@FeignClient(name = "payment-service", contextId = "payment-core", path = "/payment")
public interface PaymentFeign {
  
    @GetMapping("/refund")
    RefundPaymentVo refund(RefundPaymentDto refundPaymentDto);
}
复制代码

就会报下面的错误信息:

feign.FeignException$MethodNotAllowed: [405] during [GET] to [http://payment-service/payment/refund] [PaymentFeign#refund(RefundPaymentDto)]: [{"timestamp":"2022-03-26T18:34:47.058+00:00","status":405,"error":"Method Not Allowed","path":"/payment/refund"}]
  at feign.FeignException.clientErrorStatus(FeignException.java:221)
  at feign.FeignException.errorStatus(FeignException.java:194)
  at feign.FeignException.errorStatus(FeignException.java:185)
  at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)
  at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96)
  at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
  at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
  at org.springframework.cloud.openfeign.FeignCircuitBreakerInvocationHandler.lambda$asSupplier$1(FeignCircuitBreakerInvocationHandler.java:112)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
复制代码

二、解决方法:

OpenFeign@QueryMap注解支持将 POJO 用作 GET 参数映射。不幸的是,默认的 OpenFeign QueryMap 注解与 Spring 不兼容,因为它缺少value属性。

Spring Cloud OpenFeign 提供了等效的@SpringQueryMap注解,用于将 POJO 或 Map 参数注解为查询参数映射。

例如,RefundPaymentDto该类定义参数orderCoderefundAmount

@Data
public class RefundPaymentDto {
    /**
     * 订单号
     */
    private String orderCode;

    /**
     * 退款金额(单位:分)
     */
    private Integer refundAmount;
}
复制代码

以下 feign 客户端通过注解使用Params该类:@SpringQueryMap

@FeignClient(name = "payment-service", contextId = "payment-core", path = "/payment")
public interface PaymentFeign {
  
    @GetMapping("/refund")
    RefundPaymentVo refund(@SpringQueryMap RefundPaymentDto refundPaymentDto);
}
复制代码

如果您需要对生成的查询参数映射进行更多控制,可以实现自定义QueryMapEncoderbean。

三、总结:

@SpringQueryMap 注解的使用,简化了我们在 FeignClient 中 GET 参数的复杂定义(如果我们单个定义只能使用 @RequestParam

参考资料:1. Spring Cloud OpenFeign 官方文档

猜你喜欢

转载自juejin.im/post/7079484202789371911