我有一个带swagger2的spring-boot应用程序。我希望能够在swagger中将父对象列表映射到我的请求模型。我正在使用注释atm,但也可以使用yaml文件。
假设我有一个抽象类Person和两个子类Child和Adult。在我的请求中,我有一个Person列表,其中可以包含Child对象和Adult对象。
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Child.class, name = "CHILD"),
@JsonSubTypes.Type(value = Adult.class, name = "ADULT")})
@ApiModel(value = "Child", subTypes = {Child.class, Adult.class}, discriminator = "type")
public abstract class Person {
@ApiModelProperty(notes = "Name of the person", example = "aaron")
private String name;
@ApiModelProperty(notes = "Birthdate of the person", example = "2000-07-10")
private Date birthDate;
@ApiModelProperty(notes = "Type of the person ('CHILD' or 'ADULT')", example = "CHILD")
private String type;
Child(String name, LocalDate birthdate) {
this.name = name;
this.birthdate = birthdate;
}
Child() {
}
}
public class Adult extends Person {
private String job;
public Adult(String name, Date birthdate, String job) {
super(name, birthdate);
this.job = job;
}
Adult() {
}
}
public class Child extends Person {
private List<String> toys;
public Child(String name, Date birthdate, List<String> toys) {
super(name, birthdate);
this.toys = toys;
}
Child() {
}
}
我的请求对象如下:
public class PersonRequest {
@ApiModelProperty(notes = "Year of insert", example = "2019")
private Integer year;
@ApiModelProperty(notes = "Month of insert", example = "1")
private Integer month;
@ApiModelProperty(notes = "List of persons")
private List<Person> persons;
public SimulationRequest(Integer year, Integer month, List<Person> persons) {
this.year = year;
this.month = month;
this.persons = persons;
}
private SimulationRequest() {
}
public Integer getYear() {
return year;
}
public Integer getMonth() {
return month;
}
public List<Person> getPersons() {
return persons;
}
}
我无法得到一个正确的模型,我现在得到的是:
PersonRequest {
persons (Array[Person], optional): List of persons ,
month (integer, optional): Month of insert ,
year (integer, optional): Year of insert
}Person {
name (string, optional): Birthdate of the person ,
birthDate (string, optional): Name of the person ,
type (string, optional): Type of the person ('CHILD' or 'ADULT')
}
我想要的是:
PersonRequest {
persons (Array[Person], optional): List of persons ,
month (integer, optional): Month of insert ,
year (integer, optional): Year of insert
}Child {
name (string, optional): Birthdate of the person ,
birthDate (string, optional): Name of the person ,
type (string, optional): Type of the person ('CHILD' or 'ADULT')
toys (Array[string], optional): Toys of the child
}Adult {
name (string, optional): Birthdate of the person ,
birthDate (string, optional): Name of the person ,
type (string, optional): Type of the person ('CHILD' or 'ADULT')
job (string, optional): Job of the adult
}
并带有示例值
{
"persons": [
{
"birthdate": "2000-07-10",
"name": "aaron",
"type": "CHILD",
"toys" : ["ball","lego"]
},
{
"birthdate": "1990-07-10",
"name": "sofia",
"type": "ADULT",
"job" : "developer"
}
],
"month": 6,
"year": 2019
}
我在文档中搜索过,但似乎没有找到问题的正确答案。我已经看过这个thread并在swagger编辑器中关注了petstore示例。但我似乎没有找到如何在Swagger中使用抽象类的列表/数组。
有谁知道如何做到这一点?
谢谢!
答案 0 :(得分:1)
这是我的示例,使用 Lombok 和 Swagger 3 注释。诀窍是在具有抽象类型的排序规则上使用“oneOf”或“anyOf”。有关详细信息,请参阅 https://swagger.io/docs/specification/describing-request-body/。
@Data
public class PersonRequest {
@Schema(description = "Either Child or Adult",
anyOf = {Child .class, Adult.class})
private List<? extends Person> persons;
}
public enum PersonType {
PARENT, CHILD
}
@Data
public abstract class Person {
@Schema(notes = "Name of the person", example = "aaron")
private String name;
@Schema(notes = "Birthdate of the person", example = "2000-07-10")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date birthDate;
@Schema(notes = "Type of the person ('CHILD' or 'ADULT')", example = "CHILD")
private PersonType type; //this should be one of the enum values
Child(String name, LocalDate birthdate) {
this.name = name;
this.birthdate = birthdate;
}
Child() {
}
}
@Data
@EqualsAndHashCode(callSuper = true)
public class Adult extends Person {
private String job;
public Adult(String name, Date birthdate, String job) {
super(name, birthdate);
this.job = job;
}
Adult() {
}
}
@Data
@EqualsAndHashCode(callSuper = true)
public class Child extends Person {
private List<String> toys;
public Child(String name, Date birthdate, List<String> toys) {
super(name, birthdate);
this.toys = toys;
}
Child() {
}
}