Skip to content

Commit 5e42cf5

Browse files
committed
Content definition in @ApiResponse remove schema generated based on the returned value. Fixes #2663
1 parent 42f2c84 commit 5e42cf5

File tree

6 files changed

+154
-8
lines changed

6 files changed

+154
-8
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java

+23
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public class MethodAttributes {
128128
*/
129129
private String javadocReturn;
130130

131+
/**
132+
* The Use return type schema.
133+
*/
134+
private boolean useReturnTypeSchema;
135+
131136
/**
132137
* Instantiates a new Method attributes.
133138
* @param methodProducesNew the method produces new
@@ -493,4 +498,22 @@ public void setJavadocReturn(String javadocReturn) {
493498
public Locale getLocale() {
494499
return locale;
495500
}
501+
502+
/**
503+
* Is use return type schema boolean.
504+
*
505+
* @return the boolean
506+
*/
507+
public boolean isUseReturnTypeSchema() {
508+
return useReturnTypeSchema;
509+
}
510+
511+
/**
512+
* Sets use return type schema.
513+
*
514+
* @param useReturnTypeSchema the use return type schema
515+
*/
516+
public void setUseReturnTypeSchema(boolean useReturnTypeSchema) {
517+
this.useReturnTypeSchema = useReturnTypeSchema;
518+
}
496519
}

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public static void buildContentFromDoc(Components components, ApiResponses apiRe
181181
io.swagger.v3.oas.annotations.responses.ApiResponse apiResponseAnnotations,
182182
ApiResponse apiResponse, boolean openapi31) {
183183

184+
methodAttributes.setUseReturnTypeSchema(apiResponseAnnotations.useReturnTypeSchema());
184185
io.swagger.v3.oas.annotations.media.Content[] contentdoc = apiResponseAnnotations.content();
185186
Optional<Content> optionalContent = getContent(contentdoc, new String[0],
186187
methodAttributes.getMethodProduces(), null, components, methodAttributes.getJsonViewAnnotation(), openapi31);
@@ -620,8 +621,8 @@ else if (CollectionUtils.isEmpty(apiResponse.getContent()))
620621
setDescription(httpCode, apiResponse);
621622
}
622623
}
623-
if (apiResponse.getContent() != null
624-
&& ((isGeneric || methodAttributes.isMethodOverloaded()) && methodAttributes.isNoApiResponseDoc())) {
624+
if (apiResponse.getContent() != null && (methodAttributes.isUseReturnTypeSchema() ||
625+
((isGeneric || methodAttributes.isMethodOverloaded()) && methodAttributes.isNoApiResponseDoc()))) {
625626
// Merge with existing schema
626627
Content existingContent = apiResponse.getContent();
627628
Type type = ReturnTypeParser.getType(methodParameter);

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.LinkedHashSet;
3535
import java.util.List;
3636
import java.util.Map;
37+
import java.util.Map.Entry;
3738
import java.util.Optional;
3839
import java.util.Set;
3940

@@ -45,6 +46,7 @@
4546
import io.swagger.v3.core.converter.ResolvedSchema;
4647
import io.swagger.v3.core.util.AnnotationsUtils;
4748
import io.swagger.v3.oas.annotations.Hidden;
49+
import io.swagger.v3.oas.annotations.media.Encoding;
4850
import io.swagger.v3.oas.annotations.media.ExampleObject;
4951
import io.swagger.v3.oas.annotations.media.SchemaProperty;
5052
import io.swagger.v3.oas.models.Components;
@@ -142,7 +144,7 @@ public static Schema extractSchema(Components components, Type returnType, JsonV
142144
componentSchemas.putAll(schemaMap);
143145
}
144146
else
145-
for (Map.Entry<String, Schema> entry : schemaMap.entrySet()) {
147+
for (Entry<String, Schema> entry : schemaMap.entrySet()) {
146148
// If we've seen this schema before but find later it should be polymorphic,
147149
// replace the existing schema with this richer version.
148150
Schema existingSchema = componentSchemas.get(entry.getKey());
@@ -200,7 +202,7 @@ public static Optional<Content> getContent(io.swagger.v3.oas.annotations.media.C
200202
ExampleObject[] examples = annotationContent.examples();
201203
setExamples(mediaType, examples);
202204
addExtension(annotationContent, mediaType, openapi31);
203-
io.swagger.v3.oas.annotations.media.Encoding[] encodings = annotationContent.encoding();
205+
Encoding[] encodings = annotationContent.encoding();
204206
addEncodingToMediaType(jsonViewAnnotation, mediaType, encodings, openapi31);
205207
if (StringUtils.isNotBlank(annotationContent.mediaType())) {
206208
content.addMediaType(annotationContent.mediaType(), mediaType);
@@ -230,8 +232,11 @@ public static void mergeSchema(Content existingContent, Schema<?> schemaN, Strin
230232
if (!schemaN.equals(mediaType.getSchema())) {
231233
// Merge the two schemas for the same mediaType
232234
Schema firstSchema = mediaType.getSchema();
233-
ComposedSchema schemaObject;
234-
if (firstSchema instanceof ComposedSchema) {
235+
Schema<?> schemaObject = null;
236+
if (firstSchema == null) {
237+
schemaObject = schemaN;
238+
}
239+
else if (firstSchema instanceof ComposedSchema) {
235240
schemaObject = (ComposedSchema) firstSchema;
236241
List<Schema> listOneOf = schemaObject.getOneOf();
237242
if (!CollectionUtils.isEmpty(listOneOf) && !listOneOf.contains(schemaN))
@@ -311,8 +316,8 @@ public static void removeAnnotationsToIgnore(Class<?>... classes) {
311316
* @param openapi31 the openapi 31
312317
*/
313318
private static void addEncodingToMediaType(JsonView jsonViewAnnotation, MediaType mediaType,
314-
io.swagger.v3.oas.annotations.media.Encoding[] encodings, boolean openapi31) {
315-
for (io.swagger.v3.oas.annotations.media.Encoding encoding : encodings) {
319+
Encoding[] encodings, boolean openapi31) {
320+
for (Encoding encoding : encodings) {
316321
addEncodingToMediaType(mediaType, encoding, jsonViewAnnotation, openapi31);
317322
}
318323
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package test.org.springdoc.api.v30.app226;
2+
3+
import java.util.Map;
4+
5+
import io.swagger.v3.oas.annotations.media.Content;
6+
import io.swagger.v3.oas.annotations.media.ExampleObject;
7+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
8+
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
/**
14+
* @author bnasslahsen
15+
*/
16+
@RestController
17+
@RequestMapping
18+
public class HelloController {
19+
20+
@PostMapping("/testBoolean")
21+
@ApiResponse(
22+
useReturnTypeSchema = true,
23+
responseCode = "200",
24+
description = "OK",
25+
content = {
26+
@Content(
27+
mediaType = "*/*",
28+
examples =
29+
@ExampleObject(
30+
name = "success",
31+
value ="..."))
32+
}
33+
)
34+
public Map<String, String> HelloController() {
35+
return null;
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2022 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.app226;
26+
27+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
28+
29+
import org.springframework.boot.autoconfigure.SpringBootApplication;
30+
31+
public class SpringDocApp226Test extends AbstractSpringDocV30Test {
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
"/testBoolean": {
15+
"post": {
16+
"tags": [
17+
"hello-controller"
18+
],
19+
"operationId": "HelloController",
20+
"responses": {
21+
"200": {
22+
"description": "OK",
23+
"content": {
24+
"*/*": {
25+
"schema": {
26+
"type": "object",
27+
"additionalProperties": {
28+
"type": "string"
29+
}
30+
},
31+
"examples": {
32+
"success": {
33+
"description": "success",
34+
"value": "..."
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
},
44+
"components": {}
45+
}

0 commit comments

Comments
 (0)