Skip to content

Commit 3e8e84e

Browse files
committed
override-with-generic-response not working from 1.6.8 onwards. Fixes #1791.
1 parent dd50412 commit 3e8e84e

File tree

7 files changed

+350
-49
lines changed

7 files changed

+350
-49
lines changed

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

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -168,30 +168,25 @@ public ApiResponses build(Components components, HandlerMethod handlerMethod, Op
168168
* @return the filtered and enriched responses
169169
*/
170170
private Map<String, ApiResponse> filterAndEnrichGenericMapResponseByDeclarations(HandlerMethod handlerMethod, Map<String, ApiResponse> genericMapResponse) {
171-
Map<String, ApiResponse> result = new HashMap<>();
172-
for (Map.Entry<String, ApiResponse> genericResponse : genericMapResponse.entrySet()) {
173-
Map<String, Object> extensions = genericResponse.getValue().getExtensions();
174-
Set<Class<?>> genericExceptions = (Set<Class<?>>) extensions.get(EXTENSION_EXCEPTION_CLASSES);
175-
for (Class<?> declaredException : handlerMethod.getMethod().getExceptionTypes()) {
176-
if (genericExceptions.contains(declaredException)) {
177-
ApiResponse clone = cloneApiResponse(genericResponse.getValue());
178-
clone.getExtensions().remove(EXTENSION_EXCEPTION_CLASSES);
179-
if (operationService.getJavadocProvider() != null) {
180-
JavadocProvider javadocProvider = operationService.getJavadocProvider();
181-
Map<String, String> javadocThrows = javadocProvider.getMethodJavadocThrows(handlerMethod.getMethod());
182-
String description = javadocThrows.get(declaredException.getName());
183-
if (description == null) {
184-
description = javadocThrows.get(declaredException.getSimpleName());
185-
}
186-
if (description != null && !description.trim().isEmpty()) {
187-
clone.setDescription(description);
188-
}
171+
if (operationService.getJavadocProvider() != null) {
172+
JavadocProvider javadocProvider = operationService.getJavadocProvider();
173+
for (Map.Entry<String, ApiResponse> genericResponse : genericMapResponse.entrySet()) {
174+
Map<String, Object> extensions = genericResponse.getValue().getExtensions();
175+
Set<Class<?>> genericExceptions = (Set<Class<?>>) extensions.get(EXTENSION_EXCEPTION_CLASSES);
176+
for (Class<?> declaredException : handlerMethod.getMethod().getExceptionTypes()) {
177+
if (genericExceptions.contains(declaredException)) {
178+
Map<String, String> javadocThrows = javadocProvider.getMethodJavadocThrows(handlerMethod.getMethod());
179+
String description = javadocThrows.get(declaredException.getName());
180+
if (description == null)
181+
description = javadocThrows.get(declaredException.getSimpleName());
182+
if (description != null && !description.trim().isEmpty()) {
183+
genericResponse.getValue().setDescription(description);
184+
}
189185
}
190-
result.put(genericResponse.getKey(), clone);
191186
}
192187
}
193188
}
194-
return result;
189+
return genericMapResponse;
195190
}
196191

197192
/**
@@ -694,21 +689,4 @@ private boolean isHttpCodePresent(String httpCode, Set<io.swagger.v3.oas.annotat
694689
public static void setResponseEntityExceptionHandlerClass(Class<?> responseEntityExceptionHandlerClass) {
695690
GenericResponseService.responseEntityExceptionHandlerClass = responseEntityExceptionHandlerClass;
696691
}
697-
698-
/**
699-
* Clone api response api response.
700-
*
701-
* @param original the original
702-
* @return the api response
703-
*/
704-
private ApiResponse cloneApiResponse(ApiResponse original) {
705-
ApiResponse clone = new ApiResponse();
706-
clone.set$ref(original.get$ref());
707-
clone.setDescription(original.getDescription());
708-
clone.setContent(original.getContent());
709-
clone.setHeaders(original.getHeaders() == null ? null : new HashMap<>(original.getHeaders()));
710-
clone.setExtensions(original.getExtensions() == null ? null : new HashMap<>(original.getExtensions()));
711-
clone.setLinks(original.getLinks() == null ? null : new HashMap<>(original.getLinks()));
712-
return clone;
713-
}
714692
}

springdoc-openapi-javadoc/src/test/resources/results/app162.json

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,31 @@
3838
}
3939
],
4040
"responses": {
41+
"400": {
42+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
43+
"content": {
44+
"*/*": {
45+
"schema": {
46+
"type": "string"
47+
}
48+
}
49+
},
50+
"x-exception-class": [
51+
"test.org.springdoc.api.app162.exception.NonUniqueResultException"
52+
]
53+
},
4154
"404": {
42-
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#find(String)</code> method",
55+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
4356
"content": {
4457
"*/*": {
4558
"schema": {
4659
"type": "string"
4760
}
4861
}
49-
}
62+
},
63+
"x-exception-class": [
64+
"test.org.springdoc.api.app162.exception.NoResultException"
65+
]
5066
},
5167
"200": {
5268
"description": "the <code>@return</code> javadoc for the <code>#find(String)</code> method",
@@ -89,15 +105,31 @@
89105
"required": true
90106
},
91107
"responses": {
108+
"400": {
109+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
110+
"content": {
111+
"*/*": {
112+
"schema": {
113+
"type": "string"
114+
}
115+
}
116+
},
117+
"x-exception-class": [
118+
"test.org.springdoc.api.app162.exception.NonUniqueResultException"
119+
]
120+
},
92121
"404": {
93-
"description": "the <code>return</code> javadoc for the <code>#handleNotFoundException(NoResultException)</code> method",
122+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
94123
"content": {
95124
"*/*": {
96125
"schema": {
97126
"type": "string"
98127
}
99128
}
100-
}
129+
},
130+
"x-exception-class": [
131+
"test.org.springdoc.api.app162.exception.NoResultException"
132+
]
101133
},
102134
"200": {
103135
"description": "the <code>@return</code> javadoc for the <code>#update(String, JavadocOnlyRestDto)</code> method",
@@ -121,6 +153,32 @@
121153
"description": "This is the list method's javadoc.\n The method's signature: <code>#list()</code>",
122154
"operationId": "list",
123155
"responses": {
156+
"400": {
157+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
158+
"content": {
159+
"*/*": {
160+
"schema": {
161+
"type": "string"
162+
}
163+
}
164+
},
165+
"x-exception-class": [
166+
"test.org.springdoc.api.app162.exception.NonUniqueResultException"
167+
]
168+
},
169+
"404": {
170+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
171+
"content": {
172+
"*/*": {
173+
"schema": {
174+
"type": "string"
175+
}
176+
}
177+
},
178+
"x-exception-class": [
179+
"test.org.springdoc.api.app162.exception.NoResultException"
180+
]
181+
},
124182
"200": {
125183
"description": "the <code>@return</code> javadoc for the <code>#list()</code> method",
126184
"content": {
@@ -155,6 +213,32 @@
155213
"required": true
156214
},
157215
"responses": {
216+
"400": {
217+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
218+
"content": {
219+
"*/*": {
220+
"schema": {
221+
"type": "string"
222+
}
223+
}
224+
},
225+
"x-exception-class": [
226+
"test.org.springdoc.api.app162.exception.NonUniqueResultException"
227+
]
228+
},
229+
"404": {
230+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
231+
"content": {
232+
"*/*": {
233+
"schema": {
234+
"type": "string"
235+
}
236+
}
237+
},
238+
"x-exception-class": [
239+
"test.org.springdoc.api.app162.exception.NoResultException"
240+
]
241+
},
158242
"201": {
159243
"description": "the <code>@return</code> javadoc for the <code>#create(JavadocOnlyRestDto)</code> method",
160244
"content": {
@@ -196,7 +280,10 @@
196280
"type": "string"
197281
}
198282
}
199-
}
283+
},
284+
"x-exception-class": [
285+
"test.org.springdoc.api.app162.exception.NonUniqueResultException"
286+
]
200287
},
201288
"404": {
202289
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
@@ -206,7 +293,10 @@
206293
"type": "string"
207294
}
208295
}
209-
}
296+
},
297+
"x-exception-class": [
298+
"test.org.springdoc.api.app162.exception.NoResultException"
299+
]
210300
},
211301
"200": {
212302
"description": "the <code>@return</code> javadoc for the <code>#findStartsBy(String)</code> method",
@@ -249,4 +339,4 @@
249339
}
250340
}
251341
}
252-
}
342+
}

springdoc-openapi-javadoc/src/test/resources/results/app163.json

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,31 @@
4848
"required": true
4949
},
5050
"responses": {
51+
"400": {
52+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
53+
"content": {
54+
"*/*": {
55+
"schema": {
56+
"type": "string"
57+
}
58+
}
59+
},
60+
"x-exception-class": [
61+
"test.org.springdoc.api.app163.exception.NonUniqueResultException"
62+
]
63+
},
5164
"404": {
52-
"description": "the <code>return</code> javadoc for the <code>#handleNotFoundException(NoResultException)</code> method",
65+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
5366
"content": {
5467
"*/*": {
5568
"schema": {
5669
"type": "string"
5770
}
5871
}
59-
}
72+
},
73+
"x-exception-class": [
74+
"test.org.springdoc.api.app163.exception.NoResultException"
75+
]
6076
},
6177
"200": {
6278
"description": "the <code>@return</code> javadoc for the <code>#update(String, AnnotationOverrideForJavadocRestDto)</code> method",
@@ -91,6 +107,32 @@
91107
"required": true
92108
},
93109
"responses": {
110+
"400": {
111+
"description": "the <code>@throws NonUniqueResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
112+
"content": {
113+
"*/*": {
114+
"schema": {
115+
"type": "string"
116+
}
117+
}
118+
},
119+
"x-exception-class": [
120+
"test.org.springdoc.api.app163.exception.NonUniqueResultException"
121+
]
122+
},
123+
"404": {
124+
"description": "the <code>@throws NoResultException</code> javadoc for the <code>#findStartsBy(String)</code> method",
125+
"content": {
126+
"*/*": {
127+
"schema": {
128+
"type": "string"
129+
}
130+
}
131+
},
132+
"x-exception-class": [
133+
"test.org.springdoc.api.app163.exception.NoResultException"
134+
]
135+
},
94136
"default": {
95137
"description": "API Response 201 for #create(AnnotationOverrideForJavadocRestDto)",
96138
"content": {
@@ -135,7 +177,10 @@
135177
"type": "string"
136178
}
137179
}
138-
}
180+
},
181+
"x-exception-class": [
182+
"test.org.springdoc.api.app163.exception.NoResultException"
183+
]
139184
},
140185
"200": {
141186
"description": "API Response 200 for #findStartsBy(prefix)",
@@ -179,4 +224,4 @@
179224
}
180225
}
181226
}
182-
}
227+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package test.org.springdoc.api.v30.app191;
2+
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.web.bind.annotation.ControllerAdvice;
6+
import org.springframework.web.bind.annotation.ExceptionHandler;
7+
import org.springframework.web.bind.annotation.ResponseStatus;
8+
9+
10+
@ControllerAdvice
11+
class GlobalExceptionHandler {
12+
13+
@ResponseStatus(code = HttpStatus.FORBIDDEN)
14+
@ExceptionHandler(MyException.class)
15+
public ResponseEntity<String> handleException(MyException myException) {
16+
return ResponseEntity.status(HttpStatus.FORBIDDEN)
17+
.body(myException.getMessage());
18+
}
19+
}

springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app191/HelloController.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@
2424

2525
import java.util.List;
2626

27+
import io.swagger.v3.oas.annotations.Operation;
2728
import org.springdoc.api.annotations.ParameterObject;
2829

2930
import org.springframework.data.domain.Pageable;
3031
import org.springframework.data.domain.Sort;
3132
import org.springframework.data.domain.Sort.Direction;
3233
import org.springframework.data.web.SortDefault;
34+
import org.springframework.http.HttpStatus;
35+
import org.springframework.http.MediaType;
3336
import org.springframework.http.ResponseEntity;
37+
import org.springframework.web.bind.annotation.ExceptionHandler;
3438
import org.springframework.web.bind.annotation.GetMapping;
39+
import org.springframework.web.bind.annotation.ResponseStatus;
3540
import org.springframework.web.bind.annotation.RestController;
3641

3742
@RestController
@@ -70,4 +75,20 @@ public String getPatientList4(@SortDefault(sort = "someField",
7075
@ParameterObject Pageable pageable) {
7176
return "bla";
7277
}
78+
79+
@GetMapping(value = "/hello", produces = MediaType.TEXT_PLAIN_VALUE)
80+
@Operation(summary = "Says hello")
81+
public ResponseEntity<String> getHello() {
82+
return ResponseEntity
83+
.status(HttpStatus.OK)
84+
.body("Hello!");
85+
}
86+
87+
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
88+
@ExceptionHandler(RuntimeException.class)
89+
public ResponseEntity<String> handleException(RuntimeException runtimeException) {
90+
return ResponseEntity
91+
.status(HttpStatus.INTERNAL_SERVER_ERROR)
92+
.body(runtimeException.getMessage());
93+
}
7394
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package test.org.springdoc.api.v30.app191;
2+
3+
public class MyException extends RuntimeException {
4+
public MyException(String message){
5+
super(message);
6+
}
7+
}

0 commit comments

Comments
 (0)