feign post参数对象不加@RequestBody的使用说明

 更新时间:2021年10月23日 09:03:11   作者:miaokezhang  
这篇文章主要介绍了feign post参数对象不加@RequestBody的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

feign post参数对象不加@RequestBody

最近在做小程序调支付服务接口的一个功能,这个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的注解,有必要先学习下这两个注解的基本使用:

但是呢,一开始没想太多,调支付服务的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对象里去,至于为何,我也不太清楚,暂时知道是可以这么用的。

使用@RequestParam、@RequestBody 的正确姿势

背景

最近在使用 @RequestParam、@RequestBody 注解定义 feign 接口的时候出现一些使用上的问题,造成调用方启动的时候会报错。

详细情况

第一种情况,如下:

@PostMapping(value = "/hello2")
BetaDto hello2(String name1);

接口有且只有一个 key/value 参数,此时可以不必在 name1 参数上使用 @RequestParam 注解。通过 Feign 调用该接口的调用方可以正常启动。

第二种情况,如下:

 @PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam String name1);

接口有且只有一个 key/value 参数,此时如果对 name1 参数上使用 @RequestParam 注解,此时通过 Feign 调用该接口的调用方可启动的时候回抛出如下错误:

Caused by: java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0

意思是 @RequestParam 的 value 值不允许为空,正确的姿势如下:

 @PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam("name1") String name1);

第三种情况,如下:

@PostMapping(value = "/hello2")
BetaDto hello2(String name1, String name2);

接口存在多个 key/value 参数,此时通过 Feign 调用该接口的调用方启动的时候会抛出如下错误:

Caused by: java.lang.IllegalStateException: Method has too many Body parameters

像这种多参数(key/value)的情况必须为每个参数增加 @RequestParam 注解,正确的姿势如下:

@PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam(“name1”)  String name1, @RequestParam(“name2”)  String name2);

小结一下

在使用 @RequestParam 注解的时候,value 值必须设置,如下:

@PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam(“name1”)  String name1);

如果接口有且只有一个参数,并且该参数是 key/value 类型,则无需为该参数设置 @RequestParam 注解,如下:

@PostMapping(value = "/hello2")
BetaDto hello2(String name1);

接口存在多个参数(key/value、Json 对象)的时候,每个 key/value 类型的参数必须显示的指定 @RequestParam 注解,且必须设置对应的 value

@PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam(“name1”) String name1, RequestParam(“name2”) String name2, BetaDto betaDto);

接口无论有多个参数还是一个参数,都不需要为 Json 对象参数显示的指定 @RequestBody 注解

@PostMapping(value = "/hello1")
BetaDto hello1(BetaDto betaDto);
@PostMapping(value = "/hello2")
BetaDto hello2(@RequestParam(“name1”) String name1, RequestParam(“name2”) String name2, BetaDto betaDto);

每个接口里只允许有一个 JSON 对象类型的参数,否则通过 Feign 调用该接口的调用方启动的时候会抛出如下错误:

Caused by: java.lang.IllegalStateException: Method has too many Body parameters

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 介绍Jersey-Jersey入门基础

    介绍Jersey-Jersey入门基础

    REST不是一种新的技术,而仅仅是一个理论,实践这样的理论可以让我们的应用更加先进。
    2013-02-02
  • Java制作智能拼图游戏原理及代码

    Java制作智能拼图游戏原理及代码

    本文给大家分享的是使用Java实现智能拼图游戏的原理,以及实现的源码,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • java中字符串转整数及MyAtoi方法的实现

    java中字符串转整数及MyAtoi方法的实现

    这篇文章主要介绍了java中字符串转整数及MyAtoi方法的实现的相关资料,需要的朋友可以参考下
    2017-05-05
  • SpringCache快速使用及入门案例

    SpringCache快速使用及入门案例

    Spring Cache 是Spring 提供的一整套的缓存解决方案,它不是具体的缓存实现,本文主要介绍了SpringCache快速使用及入门案例,感兴趣的可以了解一下
    2023-08-08
  • SpringBoot下载Excel文件时,报错文件损坏的解决方案

    SpringBoot下载Excel文件时,报错文件损坏的解决方案

    这篇文章主要介绍了SpringBoot下载Excel文件时,报错文件损坏的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java获取时间打印到控制台代码实例

    Java获取时间打印到控制台代码实例

    这篇文章主要介绍了Java获取时间打印到控制台代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • springboot2.x实现oauth2授权码登陆的方法

    springboot2.x实现oauth2授权码登陆的方法

    这篇文章主要介绍了springboot2.x实现oauth2授权码登陆的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • IntelliJ IDEA连接MySQL数据库详细图解

    IntelliJ IDEA连接MySQL数据库详细图解

    今天小编就为大家分享一篇关于intellij idea连接mysql数据库详细图解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • java oshi如何查看cpu信息

    java oshi如何查看cpu信息

    这篇文章主要介绍了java oshi如何查看cpu信息,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 详解Java对象序列化为什么要使用SerialversionUID

    详解Java对象序列化为什么要使用SerialversionUID

    这篇文章主要介绍了详解Java对象序列化为什么要使用SerialversionUID,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论