Skip to content

Commit 48b61fb

Browse files
authored
Merge pull request #2403 from uc4w6c/fix_arrayschema
Fix arrayschema
2 parents d39cddb + dea674b commit 48b61fb

File tree

4 files changed

+227
-46
lines changed

4 files changed

+227
-46
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java

+51-46
Original file line numberDiff line numberDiff line change
@@ -354,58 +354,63 @@ private static void setExamples(MediaType mediaType, ExampleObject[] examples) {
354354
private static MediaType getMediaType(Schema schema, Components components, JsonView jsonViewAnnotation,
355355
io.swagger.v3.oas.annotations.media.Content annotationContent, boolean openapi31) {
356356
MediaType mediaType = new MediaType();
357-
if (!annotationContent.schema().hidden()) {
358-
if (components != null) {
359-
try {
360-
getSchema(annotationContent, components, jsonViewAnnotation, openapi31).ifPresent(mediaType::setSchema);
361-
if (annotationContent.schemaProperties().length > 0) {
362-
if (mediaType.getSchema() == null) {
363-
mediaType.schema(new Schema<Object>().type("object"));
364-
}
365-
Schema oSchema = mediaType.getSchema();
366-
for (SchemaProperty sp : annotationContent.schemaProperties()) {
367-
Class<?> schemaImplementation = sp.schema().implementation();
368-
boolean isArray = isArray(annotationContent);
369-
getSchema(sp.schema(), sp.array(), isArray, schemaImplementation, components, jsonViewAnnotation, openapi31)
370-
.ifPresent(s -> {
371-
if ("array".equals(oSchema.getType())) {
372-
oSchema.getItems().addProperty(sp.name(), s);
373-
}
374-
else {
375-
oSchema.addProperty(sp.name(), s);
376-
}
377-
});
378-
357+
if (annotationContent.schema().hidden()) {
358+
return mediaType;
359+
}
360+
if (components == null) {
361+
mediaType.setSchema(schema);
362+
return mediaType;
363+
}
364+
try {
365+
getSchema(annotationContent, components, jsonViewAnnotation, openapi31).ifPresent(mediaType::setSchema);
366+
if (annotationContent.schemaProperties().length > 0) {
367+
if (mediaType.getSchema() == null) {
368+
mediaType.schema(new Schema<Object>().type("object"));
369+
}
370+
Schema oSchema = mediaType.getSchema();
371+
for (SchemaProperty sp : annotationContent.schemaProperties()) {
372+
Class<?> schemaImplementation = sp.schema().implementation();
373+
boolean isArray = false;
374+
if (schemaImplementation == Void.class) {
375+
schemaImplementation = sp.array().schema().implementation();
376+
if (schemaImplementation != Void.class) {
377+
isArray = true;
379378
}
380379
}
381-
if (
382-
hasSchemaAnnotation(annotationContent.additionalPropertiesSchema()) &&
383-
mediaType.getSchema() != null &&
384-
!Boolean.TRUE.equals(mediaType.getSchema().getAdditionalProperties()) &&
385-
!Boolean.FALSE.equals(mediaType.getSchema().getAdditionalProperties())) {
386-
getSchemaFromAnnotation(annotationContent.additionalPropertiesSchema(), components, jsonViewAnnotation, openapi31)
387-
.ifPresent(s -> {
388-
if ("array".equals(mediaType.getSchema().getType())) {
389-
mediaType.getSchema().getItems().additionalProperties(s);
390-
}
391-
else {
392-
mediaType.getSchema().additionalProperties(s);
393-
}
394-
}
395-
);
396-
}
397-
}
398-
catch (Exception e) {
399-
if (isArray(annotationContent))
400-
mediaType.setSchema(new ArraySchema().items(new StringSchema()));
401-
else
402-
mediaType.setSchema(new StringSchema());
380+
getSchema(sp.schema(), sp.array(), isArray, schemaImplementation, components, jsonViewAnnotation, openapi31)
381+
.ifPresent(s -> {
382+
if ("array".equals(oSchema.getType())) {
383+
oSchema.getItems().addProperty(sp.name(), s);
384+
}
385+
else {
386+
oSchema.addProperty(sp.name(), s);
387+
}
388+
});
403389
}
404390
}
405-
else {
406-
mediaType.setSchema(schema);
391+
if (
392+
hasSchemaAnnotation(annotationContent.additionalPropertiesSchema()) &&
393+
mediaType.getSchema() != null &&
394+
!Boolean.TRUE.equals(mediaType.getSchema().getAdditionalProperties()) &&
395+
!Boolean.FALSE.equals(mediaType.getSchema().getAdditionalProperties())) {
396+
getSchemaFromAnnotation(annotationContent.additionalPropertiesSchema(), components, jsonViewAnnotation, openapi31)
397+
.ifPresent(s -> {
398+
if ("array".equals(mediaType.getSchema().getType())) {
399+
mediaType.getSchema().getItems().additionalProperties(s);
400+
}
401+
else {
402+
mediaType.getSchema().additionalProperties(s);
403+
}
404+
}
405+
);
407406
}
408407
}
408+
catch (Exception e) {
409+
if (isArray(annotationContent))
410+
mediaType.setSchema(new ArraySchema().items(new StringSchema()));
411+
else
412+
mediaType.setSchema(new StringSchema());
413+
}
409414
return mediaType;
410415
}
411416

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2023 the original author or authors.
7+
* * * * *
8+
* * * * * Licensed under the Apache License, Version 2.0 (the "License");
9+
* * * * * you may not use this file except in compliance with the License.
10+
* * * * * You may obtain a copy of the License at
11+
* * * * *
12+
* * * * * https://www.apache.org/licenses/LICENSE-2.0
13+
* * * * *
14+
* * * * * Unless required by applicable law or agreed to in writing, software
15+
* * * * * distributed under the License is distributed on an "AS IS" BASIS,
16+
* * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* * * * * See the License for the specific language governing permissions and
18+
* * * * * limitations under the License.
19+
* * * *
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
package test.org.springdoc.api.v30.app211;
26+
27+
import io.swagger.v3.oas.annotations.media.ArraySchema;
28+
import io.swagger.v3.oas.annotations.media.Content;
29+
import io.swagger.v3.oas.annotations.media.Schema;
30+
import io.swagger.v3.oas.annotations.media.SchemaProperty;
31+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
32+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
33+
34+
import org.springframework.http.MediaType;
35+
import org.springframework.web.bind.annotation.GetMapping;
36+
import org.springframework.web.bind.annotation.RestController;
37+
38+
@RestController
39+
public class HelloController {
40+
@ApiResponses(value = @ApiResponse(
41+
responseCode = "200",
42+
content = {
43+
@Content(
44+
mediaType = MediaType.APPLICATION_JSON_VALUE,
45+
schemaProperties = {
46+
@SchemaProperty(
47+
name = "items",
48+
array = @ArraySchema(schema = @Schema(implementation = PagedObject.class))),
49+
@SchemaProperty(name = "paging", schema = @Schema(implementation = Paging.class))
50+
}
51+
)
52+
}
53+
))
54+
@GetMapping
55+
public String index() {
56+
return null;
57+
}
58+
59+
record PagedObject(long id, String name) {}
60+
record Paging(int page, int total, int lastPage) {}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2023 the original author or authors.
7+
* * * * *
8+
* * * * * Licensed under the Apache License, Version 2.0 (the "License");
9+
* * * * * you may not use this file except in compliance with the License.
10+
* * * * * You may obtain a copy of the License at
11+
* * * * *
12+
* * * * * https://www.apache.org/licenses/LICENSE-2.0
13+
* * * * *
14+
* * * * * Unless required by applicable law or agreed to in writing, software
15+
* * * * * distributed under the License is distributed on an "AS IS" BASIS,
16+
* * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* * * * * See the License for the specific language governing permissions and
18+
* * * * * limitations under the License.
19+
* * * *
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
package test.org.springdoc.api.v30.app211;
26+
27+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
28+
29+
import org.springframework.boot.autoconfigure.SpringBootApplication;
30+
31+
public class SpringDocApp211Test extends AbstractSpringDocV30Test {
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/": {
15+
"get": {
16+
"tags": [
17+
"hello-controller"
18+
],
19+
"operationId": "index_1",
20+
"responses": {
21+
"200": {
22+
"description": "OK",
23+
"content": {
24+
"application/json": {
25+
"schema": {
26+
"type": "object",
27+
"properties": {
28+
"items": {
29+
"type": "array",
30+
"items": {
31+
"$ref": "#/components/schemas/PagedObject"
32+
}
33+
},
34+
"paging": {
35+
"$ref": "#/components/schemas/Paging"
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
}
44+
}
45+
},
46+
"components": {
47+
"schemas": {
48+
"PagedObject": {
49+
"type": "object",
50+
"properties": {
51+
"id": {
52+
"type": "integer",
53+
"format": "int64"
54+
},
55+
"name": {
56+
"type": "string"
57+
}
58+
}
59+
},
60+
"Paging": {
61+
"type": "object",
62+
"properties": {
63+
"page": {
64+
"type": "integer",
65+
"format": "int32"
66+
},
67+
"total": {
68+
"type": "integer",
69+
"format": "int32"
70+
},
71+
"lastPage": {
72+
"type": "integer",
73+
"format": "int32"
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)