diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java index d4ea9f76a..55bd18643 100644 --- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java +++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java @@ -52,6 +52,7 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.http.HttpStatus; import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; @@ -152,7 +153,7 @@ public void buildGenericResponse(Components components, Map find if (org.springframework.aop.support.AopUtils.isAopProxy(controllerAdvice)) objClz = org.springframework.aop.support.AopUtils.getTargetClass(controllerAdvice); ControllerAdviceInfo controllerAdviceInfo = new ControllerAdviceInfo(controllerAdvice); - Arrays.stream(objClz.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(ExceptionHandler.class)).forEach(methods::add); + Arrays.stream(ReflectionUtils.getAllDeclaredMethods(objClz)).filter(m -> m.isAnnotationPresent(ExceptionHandler.class)).forEach(methods::add); // for each one build ApiResponse and add it to existing responses for (Method method : methods) { if (!operationService.isHidden(method)) { diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/CommonFooErrorHandler.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/CommonFooErrorHandler.java new file mode 100644 index 000000000..21e2d2ef0 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/CommonFooErrorHandler.java @@ -0,0 +1,14 @@ +package test.org.springdoc.api.app157; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +public class CommonFooErrorHandler { + + @ExceptionHandler + @ResponseStatus(HttpStatus.CONFLICT) + public ErrorDTO onException(Exception e) { + return new ErrorDTO("Something wrong has happened"); + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/ErrorDTO.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/ErrorDTO.java new file mode 100644 index 000000000..6d2d2ecca --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/ErrorDTO.java @@ -0,0 +1,20 @@ +package test.org.springdoc.api.app157; + +public class ErrorDTO { + private String message; + + public ErrorDTO() { + } + + public ErrorDTO(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/HelloController.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/HelloController.java new file mode 100644 index 000000000..95da66ff7 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/HelloController.java @@ -0,0 +1,19 @@ +package test.org.springdoc.api.app157; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +@OpenAPIDefinition(info = @Info(title = "API Examples", version = "1.0"), tags = @Tag(name = "Operations")) +public class HelloController { + + @GetMapping("/foo") + public SimpleDTO hello() { + return new SimpleDTO("foo"); + } +} \ No newline at end of file diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SimpleDTO.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SimpleDTO.java new file mode 100644 index 000000000..d36b6ad68 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SimpleDTO.java @@ -0,0 +1,22 @@ +package test.org.springdoc.api.app157; + +public class SimpleDTO { + + private String payload; + + public SimpleDTO() { + } + + public SimpleDTO(String payload) { + this.payload = payload; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpecificFooErrorHandler.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpecificFooErrorHandler.java new file mode 100644 index 000000000..cdc6f3aea --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpecificFooErrorHandler.java @@ -0,0 +1,7 @@ +package test.org.springdoc.api.app157; + +import org.springframework.web.bind.annotation.ControllerAdvice; + +@ControllerAdvice(assignableTypes = HelloController.class) +public class SpecificFooErrorHandler extends CommonFooErrorHandler { +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpringDocApp157Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpringDocApp157Test.java new file mode 100644 index 000000000..ba5e98f78 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app157/SpringDocApp157Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.app157; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import test.org.springdoc.api.AbstractSpringDocTest; + +public class SpringDocApp157Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} + +} diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/app157.json b/springdoc-openapi-webmvc-core/src/test/resources/results/app157.json new file mode 100644 index 000000000..8c8e2f9be --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/resources/results/app157.json @@ -0,0 +1,70 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "API Examples", + "version": "1.0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "tags": [ + { + "name": "Operations" + } + ], + "paths": { + "/api/foo": { + "get": { + "tags": [ + "hello-controller" + ], + "operationId": "hello", + "responses": { + "409": { + "description": "Conflict", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SimpleDTO" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ErrorDTO": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "SimpleDTO": { + "type": "object", + "properties": { + "payload": { + "type": "string" + } + } + } + } + } +}