feign post 参数对象不加@RequestBody的用法

2023年4月11日10:09:21

最近在做小程序调支付服务接口的一个功能,这个feign接口传参真的太费事。
代码我就改造了下,不直接上真实代码。
比如小程序调支付服务的订单查询接口,支付服务那边的controller的订单查询方法是:

	@ResponseBody
    @RequestMapping(value = "/order/select", method = RequestMethod.POST)
    @ApiOperation(value = "订单查询", notes = "订单查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "queryNum", value = "查询流水", paramType = "form", required = true),
            @ApiImplicitParam(name = "queryDate", value = "流水日期", paramType = "form", required = false)
    })
    public Order qryBarcodePay(@ApiIgnore Order hero) throws Exception {

        xxxxx;
    }

这个post接口,有点奇怪,多了很多没见过的注解,而一般情况,post接口里参数对象应该是这么写的:

....
public Order qryBarcodePay(@RequestBody Order hero) throws Exception {
....
}

也就是传参的body前面一般会加上@RequestBody参数,但是支付服务的接口用到了@ApiImplicitParam和@ApiIgnore 注解,属于Swagger2的注解,有必要先学习下这两个注解的基本使用:

@ApiImplicitParam的使用
@ApiIgnore注解的使用

但是呢,一开始没想太多,调支付服务的feign接口的方法就按着平常写的post接口来:

@FeignClient(name="pay", path="pay")
public interface payFeignClient {

    @ResponseBody
    @RequestMapping(value = "/payment/order/select", method = RequestMethod.POST)
    @ApiOperation(value = "订单查询", notes = "订单查询")
    public Order qryBarcodePay(@RequestBody Order order);
}

然后在调式的时候,发现小程序调支付服务这个订单查询接口的时候,支付服务那边接受的参数对象Order字段里面的值都是null,原因是feign这边传的Order对象是RequestBody类型,而支付服务那边的接口接受参数时没有加@RequestBody,所以应该是反序列化的时候,由于格式不同,就没有成功,才出现了支付服务这边接受的参数对象Order字段里面的值都为null。

解决办法:
feign接口改成这样子就正常了:

@FeignClient(name="pay", path="pay")
public interface payFeignClient {

    @RequestMapping(value = "/payment/qry/barcode/pay", method = RequestMethod.POST)
    @ApiOperation(value = "订单查询", notes = "订单查询")
    @Headers(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultInfo<QryBarcodePayModel> qryBarcodePay(
            @RequestParam(required = true, name = "qryNo") String qryNo,
            @RequestParam(required = true, name = "hotelCode") String hotelCode);
}

这里对比一下feign和原接口的参数:
原接口:

@ApiImplicitParams({
            @ApiImplicitParam(name = "queryNum", value = "查询流水", paramType = "form", required = true),
            @ApiImplicitParam(name = "queryDate", value = "流水日期", paramType = "form", required = false)
    })
    public Order qryBarcodePay(@ApiIgnore Order hero)

feign接口:

@Headers(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultInfo<QryBarcodePayModel> qryBarcodePay(
            @RequestParam(required = true, name = "qryNo") String qryNo,
            @RequestParam(required = true, name = "hotelCode") String hotelCode);

可以看出来差别很大,首先传参,原接口是post请求,传的是一个对象,但是对象前加了@ApiIgnore 注解,相信前面给的链接学习后知道这个注解表示的是忽略的意思,也就是传参的时候,忽略掉这个对象,所以feign传的参压根就没有对象。
其次原接口对两个参数加了@ApiImplicitParam,需要提前说明的是,加了@ApiImplicitParam的两个参数queryNum、queryDate都属于Order 类里的属性。
重点看@ApiImplicitParam的paramType = “form”, required = true这两个地方,paramType="form"就表示传参以form表单的形式,所以feign接口方法上面加了@Headers(MediaType.APPLICATION_FORM_URLENCODED_VALUE)。
其次require=true就表示这两个参数是必传的。
以上就确定了feign的接口方法应该如何写,最后参数到原接口过来时,会自动将queryNum、queryDate两个参数set到Order对象里去,至于为何,我也不太清楚,暂时知道是可以这么用的。

  • 作者:miaokezhang
  • 原文链接:https://blog.csdn.net/miaokezhang/article/details/108596544
    更新时间:2023年4月11日10:09:21 ,共 2590 字。