diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index 68242fe25..2dda6e1c2 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -562,7 +562,7 @@ protected void calculatePath(List routerOperationList, Locale l if (StringUtils.isNotBlank(routerOperation.getBeanMethod())) { try { if (ArrayUtils.isEmpty(routerOperation.getParameterTypes())) { - Method[] declaredMethods = AopUtils.getTargetClass(handlerBean).getDeclaredMethods(); + Method[] declaredMethods = org.springframework.util.ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(handlerBean)); Optional methodOptional = Arrays.stream(declaredMethods) .filter(method -> routerOperation.getBeanMethod().equals(method.getName()) && method.getParameters().length == 0) .findAny(); diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/BaseHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/BaseHandler.java new file mode 100644 index 000000000..0bcc587f1 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/BaseHandler.java @@ -0,0 +1,16 @@ +package test.org.springdoc.api.app191.Handler; + +import reactor.core.publisher.Mono; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public abstract class BaseHandler { + protected abstract Mono apply (ServerRequest serverRequest); + + public Mono handle(ServerRequest serverRequest) { + return this.apply(serverRequest); + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/GetNameHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/GetNameHandler.java new file mode 100644 index 000000000..77c5f8c71 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Handler/GetNameHandler.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.app191.Handler; + +import reactor.core.publisher.Mono; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class GetNameHandler extends BaseHandler{ + @Override + protected Mono apply(ServerRequest serverRequest) { + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .bodyValue("Name API is called"); + } + + // Since handle function is present in the BaseHandler class so it is not able to detect but it should + + // Uncommenting below code will work as expected since now explicitly handle is declared here + +// @Override +// public Mono handle(ServerRequest serverRequest) { +// return super.handle(serverRequest); +// } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Router/GetNameRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Router/GetNameRouter.java new file mode 100644 index 000000000..92e1b5d40 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/Router/GetNameRouter.java @@ -0,0 +1,37 @@ +package test.org.springdoc.api.app191.Router; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.springdoc.core.annotations.RouterOperation; +import org.springdoc.core.annotations.RouterOperations; +import test.org.springdoc.api.app191.Handler.GetNameHandler; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + + +@Configuration +public class GetNameRouter { + + @Bean + @RouterOperations( + value = { + @RouterOperation(path = "/v1/name", produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET, + beanClass = GetNameHandler.class, beanMethod = "handle", operation = @Operation(operationId = "getName", + description = "get name", responses = {@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class)))}) + ) + }) + + public RouterFunction routerFunction(GetNameHandler getNameHandler) { + return RouterFunctions.route(RequestPredicates.GET("/v1/name"), getNameHandler::handle); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/SpringDocApp191Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/SpringDocApp191Test.java new file mode 100644 index 000000000..7f7cbcc24 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app191/SpringDocApp191Test.java @@ -0,0 +1,31 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.api.app191; + +import test.org.springdoc.api.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp191Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.app191" }) + static class SpringDocTestApp {} +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/app191.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/app191.json new file mode 100644 index 000000000..f1cc48b33 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/app191.json @@ -0,0 +1,37 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/v1/name": { + "get": { + "tags": [ + "get-name-handler" + ], + "description": "get name", + "operationId": "getName", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": {} +}