如何为Swagger API响应指定泛型类型类

t9eec4r0  于 2023-03-08  发布在  其他
关注(0)|答案(7)|浏览(1018)

我有大约40个API具有类似的基本响应结构,如下所示:

{
    "lastAccessed": "2015-30-08:14:21:45T",
    "createdOn": "2015-30-07:09:04:10T",
    "lastModified": "2015-30-08:14:21:45T",
    "isReadOnly": "false",
    "usersAllowed" : ["Tim", "Matt", "Christine"];
    "noOfEntries": 1,
    "object": [
        "ObjectA": {
             //here object A has its own model
         }
    ]
}

所以我有一个基本响应类,它接受类型T的泛型,如下所示:

public class Response<T> {
    @ApiModelProperty(value="Last time accessed")
    private String lastAccessed;
    @ApiModelProperty(value="Time when Created ")
    private String createdOn;
    private String lastModified;
    @ApiModelProperty(value="Created on")
    private boolean isReadOnly;
    @ApiModelProperty(value="Users that has access to the object.")
    private List<String> usersAllowed;
    private int noOfEntries;
    private T object;

    //getters and setters
}

因此,对于API A,它返回类型为的Object及其自己的字段,我返回Response作为控制器中的API响应:

public class A {
    @ApiModelProperty(value="Name")
    private String name;
    @ApiModelProperty(value="OID")
    private String id;    
    //getters and setters
}

在控制器中:响应数据= new Response();响应实体响应=新的响应实体(数据,HttpStatus. OK);
有没有一种方法可以递归地指定响应对象的模型?例如,我可以有注解@ApiOperation(response = Response.class),但它没有A的模型。

mu0hgdu0

mu0hgdu01#

我正在使用swagger 2,以下内容为我解决了这个问题。
@ApiResponse@ApiOperation中删除“response”属性。然后swagger将从方法存根中自动为您生成响应类***200 OK***(无论响应类中是否有泛型)。

@ApiOperation(value = "what your operation does")

@ApiResponses(value = { @ApiResponse(code = 200, message = "Success message") })

更新:您可以执行此简单的变通方法。只需假设您希望输出Response<MyClass>作为响应返回类型。您可以执行以下操作:

  • 在控制器类中,指定一个如下所示的空私有类

private MyResponseClass extends Response<MyClass>{}

  • 对于swagger规格,请这样指定,

@ApiResponse(code = 200, respone=MyResponseClass.class)
请记住,目前swagger还不支持泛型,以上两个只是变通方法。

vsaztqbk

vsaztqbk2#

我知道这是一个老职位,但对于其他人寻找这个问题的答案:
可以对ListSetMap响应对象执行此操作,但将忽略任何其他具有泛型类型的class class。如果使用这三个class中的任何一个,则在responseContainer字段中指定它们,并在response字段中指定您的推断类型。

@ApiResponse(code = 200, responseContainer="List", respone=java.lang.String.class)
dohp0rv5

dohp0rv53#

这个问题是在2015年问的,但我在2020年也在寻找同样的东西。:)所以,认为在这里添加我的发现是相关的。
我使用的是springdoc-openapi-ui(1.5.0),我知道它依赖于Swagger JAR,因为通用响应类接受一个泛型T,所以实际的API方法必须定义预期的类型。
如果这也是您的场景,那么NOT定义@ApiResponse -> @Contentschema属性似乎会使Swagger检查泛型类型并将其包含在模式中。

roqulrg3

roqulrg34#

根据this,最近增加了对泛型更广泛的支持。
经过测试,可以使用swagger-jaxrs2: 2.2.0swagger-annotations: 2.2.0。我还必须从响应类型中出现的类定义中删除任何@Schema注解,并且在@ApiResponse注解中删除@Content,如下所示:

@io.swagger.v3.oas.annotations.Operation(summary = "My summary",
        responses = {@ApiResponse(responseCode = "200", description = "Ok", useReturnTypeSchema = true)}
    )

在我的例子中,响应类型是GenericClass1<GenericClass2<Class3>>

jdgnovmf

jdgnovmf5#

我用的是Kotlin就像这样

@ApiOperation(
            value = "Login with email",
            response  = test(Response<AccountResponse>())
    )

fun <T : Any> test(t: T): KClass<out T> = t::class
ghhkc1vu

ghhkc1vu6#

我花了一段时间才弄明白这个问题。现在已经是2022年了(swagger 3)。虽然不理想,但类似这样的东西似乎可以用OpenAPI在API端点中返回泛型。在控制器中:

// use the Response class as the return type
@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Response.class)))
public Response<Potato> getPotato(){
     ...
     return Response<Potato>;
}

在模型中:

public class Response<T>{
    // use anyOf/allOf for specifying the types of the wrapped in class
    @Schema(anyOf = { Potato.class, Tomato.class })
    T object;

    ...
}
js4nwp54

js4nwp547#

[已解决]我得到了答案,我的解决方案已启动并运行,我正在使用OpenApi

<dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.13</version>
        </dependency>

我几乎花了2天的时间,奇迹般地得到了解决方案。

    • ApiResponse<T>是用于项目中所有响应的通用**响应类
public class ApiResponse<T extends Object> {
    @Schema(description = "status of the request failed/success", example = "SUCCESS")
    private String status;

    @Schema(description = "code to represent the status of the response", example = "200")
    private Integer statusCode;

    @Schema(description = "message for the response")
    private String message;

    private T data;

    private Integer totalCount;
    private String name;
    private Object extraData;
}
    • 解决方案**:-只要不要在泛型类型字段上放置任何@Schema注解,它就可以工作。对于泛型响应的示例,您可以在@Schema中为将用作响应的类添加example

示例:

@Getter
@Setter
@ToString
@Schema(example = "{\n" +
Some JSON example        
}")

public class SomePlanResponseDTO {

最后在@Controller

@Operation(description = "Fetch the plan", responses = {

    })
    @ApiResponses(value = {
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", useReturnTypeSchema = false, description = "plan found"),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Subscription plan not found for the current combination of filters", content = {@Content(schema = @Schema(example = "{\n" +
                    "\t\"status\": \"FAILED\",\n" +
                    "\t\"statusCode\": 404,\n" +
                    "\t\"message\": \"not found\"\n" +
                    "}"))}),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "Combination of filters in the request is not appropriate", content = {@Content(schema = @Schema(example = "{\n" +
                    "\t\"status\": \"FAILED\",\n" +
                    "\t\"statusCode\": 400,\n" +
                    "\t\"message\": \"failure\"\n" +
                    "}"))})
    }
    )
    @PostMapping(value = "/somePath", consumes = {MediaType.APPLICATION_JSON_VALUE})
    public ApiResponse<SomePlanResponseDTO > getPlans(@RequestBody SomeRequestDTO someRequestDTO) {
}

相关问题