diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index df1d7a0e3..466f67c57 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -617,9 +617,18 @@ public void applyBeanValidatorAnnotations(final MethodParameter methodParameter, if (annotations != null) { Schema schema = parameter.getSchema(); SchemaUtils.applyValidationsToSchema(schema, annotations); - if (schema instanceof ArraySchema && isParameterObject && methodParameter instanceof DelegatingMethodParameter mp) { - Field field = mp.getField(); - if (field != null && field.getAnnotatedType() instanceof AnnotatedParameterizedType paramType) { + if (schema instanceof ArraySchema && methodParameter instanceof DelegatingMethodParameter mp) { + java.lang.reflect.AnnotatedType annotatedType = null; + if (isParameterObject) { + Field field = mp.getField(); + if (field != null) { + annotatedType = field.getAnnotatedType(); + } + } else { + java.lang.reflect.Parameter param = mp.getParameter(); + annotatedType = param.getAnnotatedType(); + } + if (annotatedType instanceof AnnotatedParameterizedType paramType) { java.lang.reflect.AnnotatedType[] typeArgs = paramType.getAnnotatedActualTypeArguments(); for (java.lang.reflect.AnnotatedType typeArg : typeArgs) { List genericAnnotations = Arrays.stream(typeArg.getAnnotations()).toList(); diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt new file mode 100644 index 000000000..aa1aa2085 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt @@ -0,0 +1,57 @@ +/* + * + * * 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.v31.app19 + +import io.swagger.v3.oas.annotations.Parameter +import jakarta.validation.constraints.Max +import jakarta.validation.constraints.Min +import jakarta.validation.constraints.Size +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController +import test.org.springdoc.api.v31.AbstractKotlinSpringDocMVCTest + + +class SpringDocApp19Test : AbstractKotlinSpringDocMVCTest() { + @SpringBootApplication + class DemoApplication +} + +@RestController +@RequestMapping +class HelloController { + + @PostMapping("euroMillions") + fun euroMillions( + @Parameter(description = "the numbers") + @RequestParam + @Size(min = 5, max = 5) + numbers: List<@Max(50) @Min(1) Int>, + + @Parameter(description = "the stars") + @RequestParam + @Size(min = 2, max = 2) + stars: List<@Max(12) @Min(1) Int> + ): ResponseEntity { + return ResponseEntity.ok("ok") + } +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json new file mode 100644 index 000000000..3b6d85058 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json @@ -0,0 +1,72 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/euroMillions": { + "post": { + "tags": [ + "hello-controller" + ], + "operationId": "euroMillions", + "parameters": [ + { + "name": "numbers", + "in": "query", + "description": "the numbers", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32", + "maximum": 50, + "minimum": 1 + }, + "maxItems": 5, + "minItems": 5 + } + }, + { + "name": "stars", + "in": "query", + "description": "the stars", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32", + "maximum": 12, + "minimum": 1 + }, + "maxItems": 2, + "minItems": 2 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": {} +}