TongchengOpenSource / smart-doc

Smart-doc is a java restful api document generation tool. Smart-doc is based on interface source code analysis to generate interface documentation, completely zero-injection.
https://smart-doc-group.github.io/#/
Apache License 2.0
1.43k stars 278 forks source link

The doc api param type is wrong when the POST request use RequestParam #953

Closed skydream-xu closed 5 days ago

skydream-xu commented 1 week ago

Contact Details

No response

Version

3.0.7

Plugin

smart-doc-maven-plugin

Build tool version

3.0.7

Jdk version

17

Describe the bug (Bug描述,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

The doc api param type is wrong when the POST request use RequestParam

@PostMapping("/copy")
    public int copy(@RequestParam("id") Integer id)

image

Expected Behavior (您期望的结果,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

query-parameters

Current Behavior (当前结果,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

![Uploading image.png…]()

Steps to Reproduce (Bug产生步骤,请尽量提供用例代码。社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

see the description

Possible Solution (Bug解决建议,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

No response

Context (Bug影响描述,社区已开启国际化推广,请用文心一言、讯飞星火等辅助翻译成英文,减少社区开发者的工作)

No response

Validations

linwumingshi commented 1 week ago

In smart-doc, the @RequestParamannotation in a POST request is correctly handled as POST application/x-www-form-urlencoded or multipart/form-data content types.

skydream-xu commented 1 week ago

In smart-doc, the @RequestParamannotation in a POST request is correctly handled as POST application/x-www-form-urlencoded or multipart/form-data content types.

I only found the @RequestParam which use in a Get request in the smart-doc 。 I try to modify the request code ContentType to

    @PostMapping(value = "/copy", produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public int copy(@RequestParam("id") Integer id) {

but the apidoc still the same image

linwumingshi commented 1 week ago

In smart-doc, the @RequestParamannotation in a POST request is correctly handled as POST application/x-www-form-urlencoded or multipart/form-data content types.

I only found the @RequestParam which use in a Get request in the smart-doc 。 I try to modify the request code ContentType to

    @PostMapping(value = "/copy", produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public int copy(@RequestParam("id") Integer id) {

but the apidoc still the same image

The API info like: URL: http://127.0.0.1:8080/enum/testQueryEnum

Type: POST

Author: cqmike

Content-Type: application/x-www-form-urlencoded

Body-parameters:

Parameter Type Required Description Since
genderEnum int32 false No comments found. -

You can check the documentation for Spring MVC's @RequestParam annotation, or you can test it yourself; @RequestParam supports binding form data to method parameters in the controller.

SpringMVC @RequestParam

The first line of the documentation is: You can use the @RequestParam annotation to bind Servlet request parameters (that is, query parameters or form data) to a method argument in a controller.

skydream-xu commented 1 week ago

In smart-doc, the @RequestParamannotation in a POST request is correctly handled as POST application/x-www-form-urlencoded or multipart/form-data content types.

I only found the @RequestParam which use in a Get request in the smart-doc 。 I try to modify the request code ContentType to

    @PostMapping(value = "/copy", produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public int copy(@RequestParam("id") Integer id) {

but the apidoc still the same image

The API info like: URL: http://127.0.0.1:8080/enum/testQueryEnum

Type: POST

Author: cqmike

Content-Type: application/x-www-form-urlencoded

Body-parameters:

Parameter Type Required Description Since genderEnum int32 false No comments found. - You can check the documentation for Spring MVC's @RequestParam annotation, or you can test it yourself; @RequestParam supports binding form data to method parameters in the controller.

SpringMVC @RequestParam

The first line of the documentation is: You can use the @RequestParam annotation to bind Servlet request parameters (that is, query parameters or form data) to a method argument in a controller.

Maybe I don't describe clear , I mean the @RequestParam doc is wrong , the param type is query not body in doc , but the smart gen api doc is Body-parameters not Query-parameters

linwumingshi commented 1 week ago

In smart-doc, the @RequestParamannotation in a POST request is correctly handled as POST application/x-www-form-urlencoded or multipart/form-data content types.

I only found the @RequestParam which use in a Get request in the smart-doc 。 I try to modify the request code ContentType to

    @PostMapping(value = "/copy", produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public int copy(@RequestParam("id") Integer id) {

but the apidoc still the same image

The API info like: URL: http://127.0.0.1:8080/enum/testQueryEnum Type: POST Author: cqmike Content-Type: application/x-www-form-urlencoded

Body-parameters:

Parameter Type Required Description Since genderEnum int32 false No comments found. - You can check the documentation for Spring MVC's @RequestParam annotation, or you can test it yourself; @RequestParam supports binding form data to method parameters in the controller. SpringMVC @RequestParam The first line of the documentation is: You can use the @RequestParam annotation to bind Servlet request parameters (that is, query parameters or form data) to a method argument in a controller.

Maybe I don't describe clear , I mean the @RequestParam doc is wrong , the param type is query not body in doc , but the smart gen api doc is Body-parameters not Query-parameters


I don't believe this is an error. In Spring MVC, the @RequestParam annotation is described as binding "Servlet request parameters"—including both query parameters and form data. Therefore, it is correct for smart-doc to generate parameters annotated with @RequestParam as body parameters in a POST request, especially when the Content-Type is set to application/x-www-form-urlencoded.

Example

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * TestRequestParam Controller
 *
 * This controller demonstrates the usage of the `@RequestParam` annotation in a POST request.
 * It binds a request parameter (from either the query string or form data) to a method parameter.
 *
 * @author test
 * @version 1.0.0
 * @since 2024-11-18 15:21:47
 */
@RequestMapping
@RestController
public class TestRequestParam {

    /**
     * Example method for handling POST requests with `@RequestParam`.
     * <p>
     * Accepts a single integer parameter `id` from the request, which can be passed as a
     * query parameter or form data.
     * <p>
     * Example usage:
     * - As a query parameter:
     *   {@code curl --location --request POST 'http://127.0.0.1:28080/testRequestParamInPost?id=1'}
     * - As form data:
     *   {@code curl --location 'http://127.0.0.1:28080/testRequestParamInPost' --data 'id=1'}
     *
     * @param id The ID parameter to bind from the request.
     * @return The ID value provided in the request.
     */
    @PostMapping("/testRequestParamInPost")
    public Integer testRequestParamInPost(@RequestParam("id") Integer id) {
        return id;
    }
}

Example of Using @RequestParam Annotation

Sample Method

@PostMapping("/testRequestParamInPost")
public Integer testRequestParamInPost(@RequestParam("id") Integer id) {
    return id;
}

Request Examples

  1. Using Query Parameter:

    curl --location --request POST 'http://127.0.0.1:28080/testRequestParamInPost?id=1'
  2. Using Form Data:

    curl --location 'http://127.0.0.1:28080/testRequestParamInPost' --data 'id=1'

Explanation


jasonkung22 commented 1 week ago

The problem can also cause the object's nested parameter structure to be incorrect.

Example:

@RestController
@RequestMapping
public class QueryPostController {

    /**
     * 测试query+body参数
     * @param gender        性别数据
     * @param testBodyParam 测试参数
     * @return 性别数据字典
     *
     * @author cqmike
     * @since 1.0.0
     */
    @PostMapping("/post/testQueryAndBody")
    public Integer testJsonValueQueryEnum(@RequestParam("gender") Integer gender,
            @RequestBody TestBodyParam testBodyParam) {
        return null;
    }

    @Data
    public static class TestBodyParam {

        /**
         * 测试参数1
         */
        private TestBodyObjectParam test1;
        /**
         * 测试参数2
         */
        private TestBodyObjectParam test2;
        /**
         * 测试参数3
         */
        private TestBodyObjectParam test3;
    }

    @Data
    public static class TestBodyObjectParam {

        /**
         * 测试参数1
         */
        private String test1;
        /**
         * 测试参数2
         */
        private String test2;
        /**
         * 测试参数3
         */
        private String test3;
    }
}

Expected Behavior:

image

Current Behavior:

image