@@ -94,7 +94,8 @@ public ApiResponses build(Components components, HandlerMethod handlerMethod, Op
9494 apiResponsesFromDoc .forEach (apiResponses ::addApiResponse );
9595 // for each one build ApiResponse and add it to existing responses
9696 // Fill api Responses
97- computeResponse (components , handlerMethod .getReturnType (), apiResponses , methodAttributes , false );
97+ computeResponseFromDoc (components , handlerMethod .getReturnType (), apiResponses , methodAttributes );
98+ buildApiResponses (components , handlerMethod .getReturnType (), apiResponses , methodAttributes );
9899 return apiResponses ;
99100 }
100101
@@ -117,26 +118,27 @@ public void buildGenericResponse(Components components, Map<String, Object> find
117118 if (reqMappringMethod != null )
118119 methodProduces = reqMappringMethod .produces ();
119120 Map <String , ApiResponse > controllerAdviceInfoApiResponseMap = controllerAdviceInfo .getApiResponseMap ();
120- Map <String , ApiResponse > apiResponses = computeResponse (components , new MethodParameter (method , -1 ), new ApiResponses (),
121- new MethodAttributes (methodProduces , springDocConfigProperties .getDefaultConsumesMediaType (),
122- springDocConfigProperties .getDefaultProducesMediaType (), controllerAdviceInfoApiResponseMap ), true );
121+ MethodParameter methodParameter = new MethodParameter (method , -1 );
122+ ApiResponses apiResponsesOp = new ApiResponses ();
123+ MethodAttributes methodAttributes = new MethodAttributes (methodProduces , springDocConfigProperties .getDefaultConsumesMediaType (),
124+ springDocConfigProperties .getDefaultProducesMediaType (), controllerAdviceInfoApiResponseMap );
125+ Map <String , ApiResponse > apiResponses = computeResponseFromDoc (components , methodParameter , apiResponsesOp , methodAttributes );
126+ buildGenericApiResponses (components , methodParameter , apiResponsesOp , methodAttributes );
123127 apiResponses .forEach (controllerAdviceInfoApiResponseMap ::put );
124128 }
125129 }
126130 controllerAdviceInfos .add (controllerAdviceInfo );
127131 }
128132 }
129133
130- private Map <String , ApiResponse > computeResponse (Components components , MethodParameter methodParameter , ApiResponses apiResponsesOp ,
131- MethodAttributes methodAttributes , boolean isGeneric ) {
134+ private Map <String , ApiResponse > computeResponseFromDoc (Components components , MethodParameter methodParameter , ApiResponses apiResponsesOp ,
135+ MethodAttributes methodAttributes ) {
132136 // Parsing documentation, if present
133137 Set <io .swagger .v3 .oas .annotations .responses .ApiResponse > responsesArray = getApiResponses (methodParameter .getMethod ());
134138 if (!responsesArray .isEmpty ()) {
135139 methodAttributes .setWithApiResponseDoc (true );
136- if (!springDocConfigProperties .isOverrideWithGenericResponse ())
137- for (String key : methodAttributes .getGenericMapResponse ().keySet ())
138- apiResponsesOp .remove (key );
139140 for (io .swagger .v3 .oas .annotations .responses .ApiResponse apiResponseAnnotations : responsesArray ) {
141+ String httpCode = apiResponseAnnotations .responseCode ();
140142 ApiResponse apiResponse = new ApiResponse ();
141143 if (StringUtils .isNotBlank (apiResponseAnnotations .ref ())) {
142144 apiResponse .$ref (apiResponseAnnotations .ref ());
@@ -150,10 +152,9 @@ private Map<String, ApiResponse> computeResponse(Components components, MethodPa
150152 apiResponse .extensions (extensions );
151153 AnnotationsUtils .getHeaders (apiResponseAnnotations .headers (), methodAttributes .getJsonViewAnnotation ())
152154 .ifPresent (apiResponse ::headers );
153- apiResponsesOp .addApiResponse (apiResponseAnnotations . responseCode () , apiResponse );
155+ apiResponsesOp .addApiResponse (httpCode , apiResponse );
154156 }
155157 }
156- buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , isGeneric );
157158 return apiResponsesOp ;
158159 }
159160
@@ -180,32 +181,56 @@ public static void buildContentFromDoc(Components components, ApiResponses apiRe
180181 else
181182 apiResponse .content (newContent );
182183 }
184+ else {
185+ apiResponse .content (existingContent );
186+ }
183187 }
184188 else {
185189 optionalContent .ifPresent (apiResponse ::content );
186190 }
187191 }
188192
189- private void buildApiResponses (Components components , MethodParameter methodParameter , ApiResponses apiResponsesOp ,
190- MethodAttributes methodAttributes , boolean isGeneric ) {
191- if (!CollectionUtils .isEmpty (apiResponsesOp ) && ( apiResponsesOp . size () != methodAttributes . getGenericMapResponse (). size () || isGeneric ) ) {
193+ private void buildGenericApiResponses (Components components , MethodParameter methodParameter , ApiResponses apiResponsesOp ,
194+ MethodAttributes methodAttributes ) {
195+ if (!CollectionUtils .isEmpty (apiResponsesOp )) {
192196 // API Responses at operation and @ApiResponse annotation
193197 for (Map .Entry <String , ApiResponse > entry : apiResponsesOp .entrySet ()) {
194198 String httpCode = entry .getKey ();
195199 ApiResponse apiResponse = entry .getValue ();
196- buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse ,
197- isGeneric );
200+ buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse , true );
198201 }
199202 }
200203 else {
201204 // Use response parameters with no description filled - No documentation
202205 // available
203- String httpCode = evaluateResponseStatus (methodParameter .getMethod (), methodParameter .getMethod ().getClass (), isGeneric );
206+ String httpCode = evaluateResponseStatus (methodParameter .getMethod (), methodParameter .getMethod ().getClass (), true );
204207 ApiResponse apiResponse = methodAttributes .getGenericMapResponse ().containsKey (httpCode ) ? methodAttributes .getGenericMapResponse ().get (httpCode )
205208 : new ApiResponse ();
206209 if (httpCode != null )
207- buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse ,
208- isGeneric );
210+ buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse , true );
211+ }
212+ }
213+
214+ private void buildApiResponses (Components components , MethodParameter methodParameter , ApiResponses apiResponsesOp ,
215+ MethodAttributes methodAttributes ) {
216+ Map <String , ApiResponse > genericMapResponse = methodAttributes .getGenericMapResponse ();
217+ if (!CollectionUtils .isEmpty (apiResponsesOp ) && apiResponsesOp .size () > genericMapResponse .size ()) {
218+ // API Responses at operation and @ApiResponse annotation
219+ for (Map .Entry <String , ApiResponse > entry : apiResponsesOp .entrySet ()) {
220+ String httpCode = entry .getKey ();
221+ if (!genericMapResponse .containsKey (httpCode )) {
222+ ApiResponse apiResponse = entry .getValue ();
223+ buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse , false );
224+ }
225+ }
226+ }
227+ else {
228+ // Use response parameters with no description filled - No documentation
229+ // available
230+ String httpCode = evaluateResponseStatus (methodParameter .getMethod (), methodParameter .getMethod ().getClass (), false );
231+ ApiResponse apiResponse = new ApiResponse ();
232+ if (httpCode != null )
233+ buildApiResponses (components , methodParameter , apiResponsesOp , methodAttributes , httpCode , apiResponse , false );
209234 }
210235 }
211236
@@ -269,7 +294,7 @@ private Type getReturnType(MethodParameter methodParameter) {
269294 return returnType ;
270295 }
271296
272- private Schema calculateSchema (Components components , Type returnType , JsonView jsonView , Annotation [] annotations ) {
297+ private Schema <?> calculateSchema (Components components , Type returnType , JsonView jsonView , Annotation [] annotations ) {
273298 return !isVoid (returnType ) ? extractSchema (components , returnType , jsonView ,annotations ) : null ;
274299 }
275300
@@ -297,7 +322,8 @@ else if (CollectionUtils.isEmpty(apiResponse.getContent()))
297322 && ((isGeneric || methodAttributes .isMethodOverloaded ()) && methodAttributes .isNoApiResponseDoc ())) {
298323 // Merge with existing schema
299324 Content existingContent = apiResponse .getContent ();
300- Schema <?> schemaN = calculateSchema (components , methodParameter .getGenericParameterType (),
325+ Type type = ReturnTypeParser .getType (methodParameter );
326+ Schema <?> schemaN = calculateSchema (components , type ,
301327 methodAttributes .getJsonViewAnnotation (), methodParameter .getParameterAnnotations ());
302328 if (schemaN != null && ArrayUtils .isNotEmpty (methodAttributes .getMethodProduces ()))
303329 Arrays .stream (methodAttributes .getMethodProduces ()).forEach (mediaTypeStr -> mergeSchema (existingContent , schemaN , mediaTypeStr ));
@@ -307,7 +333,7 @@ else if (CollectionUtils.isEmpty(apiResponse.getContent()))
307333
308334 public static void setDescription (String httpCode , ApiResponse apiResponse ) {
309335 try {
310- HttpStatus httpStatus = HttpStatus .valueOf (Integer .valueOf (httpCode ));
336+ HttpStatus httpStatus = HttpStatus .valueOf (Integer .parseInt (httpCode ));
311337 apiResponse .setDescription (httpStatus .getReasonPhrase ());
312338 }
313339 catch (IllegalArgumentException e ) {
0 commit comments