@JsonView ignored for subclasses
I am having a parent class with subclasses. I am using the parent class for @RestController methods' @RequestBody parameters and for return values. And I am using different @JsonView annotations on the classes' fields, the method parameters and return value types.
When generating the OpenAPI Description, the request and response body content schemas contain an incorrect selection of the classes' fields.
public interface Input {}
public interface Output {}
@JsonSubTypes({
@JsonSubTypes.Type(value = A1.class),
@JsonSubTypes.Type(value = A2.class),
})
public static abstract class A {
@JsonView(Input.class)
public String a_in;
@JsonView(Output.class)
public String a_out;
}
@JsonTypeName("A1")
public static class A1 extends A {
@JsonView(Input.class)
public String a1_in;
@JsonView(Output.class)
public String a1_out;
}
@JsonTypeName("A2")
public static class A2 extends A {
@JsonView(Input.class)
public String a2_in;
@JsonView(Output.class)
public String a2_out;
}
@PutMapping("/a")
public void createA(@JsonView(Input.class) @RequestBody A a) {
}
@GetMapping("/a/{id}")
public @JsonView(Output.class) A getA(@PathVariable("id") String id) {
return new A1();
}
This is the actual OpenAPI Description getting generated:
{
"openapi" : "3.0.1",
"info" : {
"title" : "OpenAPI definition",
"version" : "v0"
},
"servers" : [ {
"url" : "http://localhost:8080",
"description" : "Generated server url"
} ],
"paths" : {
"/a" : {
"put" : {
"tags" : [ "demo-application" ],
"operationId" : "createA",
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"oneOf" : [ {
"$ref" : "#/components/schemas/A1"
}, {
"$ref" : "#/components/schemas/A2"
} ]
}
}
},
"required" : true
},
"responses" : {
"200" : {
"description" : "OK"
}
}
}
},
"/a/{id}" : {
"get" : {
"tags" : [ "demo-application" ],
"operationId" : "getA",
"parameters" : [ {
"name" : "id",
"in" : "path",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"*/*" : {
"schema" : {
"oneOf" : [ {
"$ref" : "#/components/schemas/A1"
}, {
"$ref" : "#/components/schemas/A2"
} ]
}
}
}
}
}
}
}
},
"components" : {
"schemas" : {
"A1" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Input"
}, {
"type" : "object",
"properties" : {
"a_out" : {
"type" : "string"
},
"a1_in" : {
"type" : "string"
},
"a1_out" : {
"type" : "string"
}
}
} ]
},
"A2" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Input"
}, {
"type" : "object",
"properties" : {
"a_out" : {
"type" : "string"
},
"a2_in" : {
"type" : "string"
},
"a2_out" : {
"type" : "string"
}
}
} ]
},
"A_Input" : {
"type" : "object",
"properties" : {
"a_in" : {
"type" : "string"
}
}
}
}
}
}
What I would expect instead:
- The response body content schema for
GET /a/{id}should only include*_outproperties. - The request body content schema for
PUT /ashould only include*_inproperties.
I.e. something along these lines:
{
"openapi" : "3.0.1",
"info" : {
"title" : "OpenAPI definition",
"version" : "v0"
},
"servers" : [ {
"url" : "http://localhost:8080",
"description" : "Generated server url"
} ],
"paths" : {
"/a" : {
"put" : {
"tags" : [ "demo-application" ],
"operationId" : "createA",
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"oneOf" : [ {
"$ref" : "#/components/schemas/A1_Input"
}, {
"$ref" : "#/components/schemas/A2_Input"
} ]
}
}
},
"required" : true
},
"responses" : {
"200" : {
"description" : "OK"
}
}
}
},
"/a/{id}" : {
"get" : {
"tags" : [ "demo-application" ],
"operationId" : "getA",
"parameters" : [ {
"name" : "id",
"in" : "path",
"required" : true,
"schema" : {
"type" : "string"
}
} ],
"responses" : {
"200" : {
"description" : "OK",
"content" : {
"*/*" : {
"schema" : {
"oneOf" : [ {
"$ref" : "#/components/schemas/A1_Output"
}, {
"$ref" : "#/components/schemas/A2_Output"
} ]
}
}
}
}
}
}
}
},
"components" : {
"schemas" : {
"A1_Input" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Input"
}, {
"type" : "object",
"properties" : {
"a1_in" : {
"type" : "string"
}
}
} ]
},
"A2_Input" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Input"
}, {
"type" : "object",
"properties" : {
"a2_in" : {
"type" : "string"
}
}
} ]
},
"A_Input" : {
"type" : "object",
"properties" : {
"a_in" : {
"type" : "string"
}
}
},
"A1_Output" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Output"
}, {
"type" : "object",
"properties" : {
"a1_out" : {
"type" : "string"
}
}
} ]
},
"A2_Output" : {
"type" : "object",
"allOf" : [ {
"$ref" : "#/components/schemas/A_Output"
}, {
"type" : "object",
"properties" : {
"a2_out" : {
"type" : "string"
}
}
} ]
},
"A_Output" : {
"type" : "object",
"properties" : {
"a_out" : {
"type" : "string"
}
}
}
}
}
}
I have tried adding @Schema(subTypes = {A1.class, A2.class}) to A but that did not help either.
I have pushed a minimal reproducible example to GitHub.
Spring Boot version: 2.7.2 springdoc-openapi version: 1.6.9 springdoc-openapi modules: common, ui, webmvc-core Java, OpenJDK 15.0.1