feign post parameter object without @ RequestBody instructions

  • 2021-11-30 00:03:36
  • OfStack

Directory feign post parameter object does not add @ RequestBody solution. Here, compare the parameters of feign and original interface under 1, use @ RequestParam, @ RequestBody. Correct posture background details summary under 1

feign post parameter object without @ RequestBody

Recently, I am doing a small program to adjust one function of the payment service interface, and this feign interface is really too troublesome.

I changed the code, not directly on the real code.

For example, the small program adjusts the order query interface of the payment service, and the order query method of controller on the payment service side is:


 @ResponseBody
    @RequestMapping(value = "/order/select", method = RequestMethod.POST)
    @ApiOperation(value = " Order inquiry ", notes = " Order inquiry ")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "queryNum", value = " Query flow ", paramType = "form", required = true),
            @ApiImplicitParam(name = "queryDate", value = " Flow date ", paramType = "form", required = false)
    })
    public Order qryBarcodePay(@ApiIgnore Order hero) throws Exception {
        xxxxx;
    }

This post interface is a bit strange, and there are many annotations that have not been seen before. In 1 case, the parameter object in post interface should be written as follows:


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

That is to say, the @ RequestBody parameter will be added in the first 1 of body, but the interface of payment service uses @ ApiImplicitParam and @ ApiIgnore annotations, which belong to Swagger2 annotations. It is necessary to learn the basic use of these two annotations first:

Use of @ ApiImplicitParam Use of @ ApiIgnore annotations

However, 1 didn't think too much at first, and the method of adjusting the feign interface of payment service was according to the usual post interface:


@FeignClient(name="pay", path="pay")
public interface payFeignClient {
    @ResponseBody
    @RequestMapping(value = "/payment/order/select", method = RequestMethod.POST)
    @ApiOperation(value = " Order inquiry ", notes = " Order inquiry ")
    public Order qryBarcodePay(@RequestBody Order order);
}

And then in the mode, When it is found that the small program adjusts the order query interface of payment service, The values in the Order field of the parameter object accepted by the payment service side are all null, because the Order object transmitted by the feign side is of RequestBody type, while the interface of the payment service side does not add @ RequestBody when accepting parameters, so it should be deserialized. Because of different formats, it is unsuccessful, and the values in the Order field of the parameter object accepted by the payment service side are all null.

Solution

It is normal to change the feign interface to this:


@FeignClient(name="pay", path="pay")
public interface payFeignClient {
    @RequestMapping(value = "/payment/qry/barcode/pay", method = RequestMethod.POST)
    @ApiOperation(value = " Order inquiry ", notes = " Order inquiry ")
    @Headers(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResultInfo<QryBarcodePayModel> qryBarcodePay(
            @RequestParam(required = true, name = "qryNo") String qryNo,
            @RequestParam(required = true, name = "hotelCode") String hotelCode);
}

Here compare the parameters of feign and the original interface under 1

Original interface:


@ApiImplicitParams({
            @ApiImplicitParam(name = "queryNum", value = " Query flow ", paramType = "form", required = true),
            @ApiImplicitParam(name = "queryDate", value = " Flow date ", paramType = "form", required = false)
    })
    public Order qryBarcodePay(@ApiIgnore Order hero)

feign interface:


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

It can be seen that there is a big difference. First, the parameter is transmitted. The original interface is post request, and an object is transmitted. However, the @ ApiIgnore annotation is added before the object. I believe that after learning the link given earlier, I know that this annotation means ignoring, that is, when transmitting parameters, this object is ignored, so the parameter transmitted by feign has no object at all.

Secondly, the original interface adds @ ApiImplicitParam to two parameters. It should be explained in advance that the two parameters queryNum and queryDate added with @ ApiImplicitParam belong to the attributes in Order class.

Focus on paramType = "form" and required = true in @ ApiImplicitParam. paramType = "form" means that the reference is passed in the form of form form, so the feign interface method is added


@Headers(MediaType.APPLICATION_FORM_URLENCODED_VALUE)

Secondly, require=true means that these two parameters are required to be passed.

The above determines how to write the interface method of feign. When the final parameters come to the original interface, the two parameters queryNum and queryDate will be automatically put into the Order object. As for why, I am not sure, but I know that it can be used in this way for the time being.

Use the correct posture of @ RequestParam, @ RequestBody

Background

Recently, when using @ RequestParam and @ RequestBody annotations to define the feign interface, there were some usage problems, which caused the caller to report an error when starting.

Details

The first case is as follows:


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

The interface has only one key/value parameter, so you don't have to use the @ RequestParam annotation on the name1 parameter. Callers that call this interface through Feign can start normally.

The second case is as follows:


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

The interface has and only has 1 key/value parameter. If the @ RequestParam annotation is used on the name1 parameter at this time, the caller who calls the interface through Feign will throw the following error when it starts:

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

It means that the value value of @ RequestParam is not allowed to be empty. The correct gesture is as follows:


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

The third case is as follows:


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

Interface has multiple key/value parameters, and callers calling the interface via Feign will throw the following error when they start:

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

In a multi-parameter situation like this (key/value), you must add a @ RequestParam annotation to each parameter. The correct gesture is as follows:


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

Summary 1

When using the @ RequestParam annotation, the value value must be set as follows:


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

If the interface has only 1 parameter and the parameter is of type key/value, there is no need to set the @ RequestParam annotation for that parameter, as follows:


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

When the interface has multiple parameters (key/value, Json object), each parameter of key/value type must display the specified @ RequestParam annotation, and the corresponding value must be set


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

The interface does not need to specify the @ RequestBody annotation for the Json object parameter display, whether it has multiple parameters or one parameter


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

Only one parameter of JSON object type is allowed in each interface, otherwise the caller who calls this interface through Feign will throw the following error when starting:

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


Related articles: