我正在尝试使用Swagger UI来创建和部署我的文档以及使用Spring Boot编写的API。我知道Swagger提供了一些注释来帮助在实际的控制器类中编写文档,但是我很难让它们做我需要的事情。
我的问题是我有一个通用的DTO类,每次调用我的API都会返回该类。此DTO具有用于通用对象的contents
字段。如果我直接使用对象,我知道我可以使用类似的东西
@ApiResponse(responseCode = "200", description = "Customer found",
content = @Content(
schema = @Schema(implementation = Customer.class)))
以便提供对象的JSON表示形式的规范。但是,由于我将所有内容包装在特定的ResponseDTO
类中,因此我需要一种方法来指定contents
字段的外观,并且我不确定可以使用哪些注释来完成此操作。我觉得肯定应该有类似的东西
@ApiResponse(responseCode = "200", description = "Customer found",
content = @Content(
schema = @Schema(implementation = DTO.class,
fields = { "contents" = @Schema(implementation = Customer.class)})))
或类似的东西。我还无法找到有关如何真正完成此操作的说明。我的直觉表明应该有一种方法可以将模式放入模式中,但是也许还有另一种我尚未考虑的解决方案。任何帮助或寻找方向将不胜感激。预先感谢。
答案 0 :(得分:3)
我知道这篇文章已经过时了,但我还是会发布这个,以防有人遇到类似的问题。
我还必须返回一个对象列表,其中这些对象的字段之一必须根据某些请求参数进行更改。为了在 Swagger 中记录这些子模式(如您所说的模式内的模式),您可以使用 @Schema
注释的 oneOf
attribute 并提供您的通用类的列表。< /p>
这是一个例子:
Customer.java
:
public class Customer {
// Some other fields...
@Schema(
description = "List of generic contents inside Customer",
oneOf = {Bar.class, Foo.class})
private List<IContent> contents;
}
IContent.java
只是一些接口(或者它可以是泛型类的任何超类):
public interface IContent extends Serializable { }
假设 Foo.java
和 Bar.java
是您的两个泛型类:
public class Bar implements IContent {
@Schema(description = "Some dummy name field inside Bar")
private String dummyName;
@Schema(description = "Some dummy number field inside Bar")
private Integer dummyNo;
}
public class Foo implements IContent {
@Schema(description = "Some dummy ID field inside Foo")
private Long contentID;
}
如果您有不同的需求而不是记录通用对象列表,请参阅 allOf and anyOf attributes 以了解其他类型的子模式属性。
答案 1 :(得分:0)
您似乎正在反向进行此操作。我通过使用http://swagger.io
上的编辑器创建一个指定API的.yaml文件来完成此操作这样,您的.yaml文件可以为每种数据类型指定不同的DTO,并且可以为每种API指定其返回的类型。
此外,您不会发布ResponseDTO类的外观。希望您已将其概括化:
public class ResponseDTO<T> {
public T getData() { … }
…
}
但是我不确定甚至拥有自己的对象也不是一个好主意。在我过去的一些项目中,我们为每种数据类型定义了一个单独的响应类,但是它们都做同样的事情!您的框架可能已经为您编写了这样的类。
您正在使用Spring Boot,这就是我所使用的。对于Spring,该类为org.springframework.http.ResponseEntity
。 (其他框架可能对此有自己的版本。)并且它已被泛化,因此您可以向其中添加任何数据类型的内容。但是Swagger要求您指定添加内容的类型,而不是ResponseEntity
类本身。您的ResponseDTO班级正在妨碍您。
因此,如果您想返回一种CustomProduct类型,则您用招摇产生的注释将指定CustomProduct.class,并且您的服务方法将如下所示:
… (more annotations)
@ApiResponses(value = {
@ApiResponse(code=200, message="Found", response=CustomProduct.class)
})
public ResonseEntity<CustomProduct> getCustomProduct(…) {
CustomProduct myCustomProduct = retrieveCustomProduct(…);
return new ResponseEntity<>(myCustomProduct, HTTPStatus.OK);
}
答案 2 :(得分:0)
我成功使用@Schema标记了类的字段,并且可以正常工作,但是我经常使用它来提供地图信息。
class CreateReq extends DTO {
@Schema(description="",
implementation = Products.class)
Map<String,Map<String,Object>> products;
}
// For openapi document only
private static class Products {
ProductFields productId1;
ProductFields productId2;
}
// For openapi document only
private static class ProductFields {
String field1;
Object field2;
}