Skip to content

Commit 01eba0d

Browse files
committed
Merge branch 'edudar-patch-1'
2 parents cc96c71 + 2d4f84e commit 01eba0d

File tree

5 files changed

+162
-6
lines changed

5 files changed

+162
-6
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java

+21-6
Original file line numberDiff line numberDiff line change
@@ -618,16 +618,20 @@ public void applyBeanValidatorAnnotations(final Parameter parameter, final List<
618618
*/
619619
public void applyBeanValidatorAnnotations(final RequestBody requestBody, final List<Annotation> annotations, boolean isOptional) {
620620
Map<String, Annotation> annos = new HashMap<>();
621-
boolean requestBodyRequired = false;
621+
boolean springRequestBodyRequired = false;
622+
boolean swaggerRequestBodyRequired = false;
622623
if (!CollectionUtils.isEmpty(annotations)) {
623624
annotations.forEach(annotation -> annos.put(annotation.annotationType().getSimpleName(), annotation));
624-
requestBodyRequired = annotations.stream()
625+
springRequestBodyRequired = annotations.stream()
625626
.filter(annotation -> org.springframework.web.bind.annotation.RequestBody.class.equals(annotation.annotationType()))
626627
.anyMatch(annotation -> ((org.springframework.web.bind.annotation.RequestBody) annotation).required());
628+
swaggerRequestBodyRequired = annotations.stream()
629+
.filter(annotation -> io.swagger.v3.oas.annotations.parameters.RequestBody.class.equals(annotation.annotationType()))
630+
.anyMatch(annotation -> ((io.swagger.v3.oas.annotations.parameters.RequestBody) annotation).required());
627631
}
628632
boolean validationExists = Arrays.stream(ANNOTATIONS_FOR_REQUIRED).anyMatch(annos::containsKey);
629633

630-
if (validationExists || (!isOptional && requestBodyRequired))
634+
if (validationExists || (!isOptional && (springRequestBodyRequired || swaggerRequestBodyRequired)))
631635
requestBody.setRequired(true);
632636
Content content = requestBody.getContent();
633637
for (MediaType mediaType : content.values()) {
@@ -766,14 +770,25 @@ private boolean isRequestBodyParam(RequestMethod requestMethod, ParameterInfo pa
766770

767771
return (isBodyAllowed && (parameterInfo.getParameterModel() == null || parameterInfo.getParameterModel().getIn() == null) && !delegatingMethodParameter.isParameterObject())
768772
&&
769-
((methodParameter.getParameterAnnotation(io.swagger.v3.oas.annotations.parameters.RequestBody.class) != null
770-
|| methodParameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestBody.class) != null
771-
|| AnnotatedElementUtils.findMergedAnnotation(Objects.requireNonNull(methodParameter.getMethod()), io.swagger.v3.oas.annotations.parameters.RequestBody.class) != null)
773+
(checkRequestBodyAnnotation(methodParameter)
772774
|| checkOperationRequestBody(methodParameter)
773775
|| checkFile(methodParameter)
774776
|| Arrays.asList(methodAttributes.getMethodConsumes()).contains(MULTIPART_FORM_DATA_VALUE));
775777
}
776778

779+
/**
780+
* Checks whether Swagger's or Spring's RequestBody annotation is present on a parameter or method
781+
*
782+
* @param methodParameter the method parameter
783+
* @return the boolean
784+
*/
785+
private boolean checkRequestBodyAnnotation(MethodParameter methodParameter) {
786+
return methodParameter.hasParameterAnnotation(org.springframework.web.bind.annotation.RequestBody.class)
787+
|| methodParameter.hasParameterAnnotation(io.swagger.v3.oas.annotations.parameters.RequestBody.class)
788+
|| AnnotatedElementUtils.isAnnotated(Objects.requireNonNull(methodParameter.getParameter()), io.swagger.v3.oas.annotations.parameters.RequestBody.class)
789+
|| AnnotatedElementUtils.isAnnotated(Objects.requireNonNull(methodParameter.getMethod()), io.swagger.v3.oas.annotations.parameters.RequestBody.class);
790+
}
791+
777792
/**
778793
* Check file boolean.
779794
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package test.org.springdoc.api.v30.app230;
2+
3+
import org.springframework.web.bind.annotation.PostMapping;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
/**
8+
* @author edudar
9+
*/
10+
@RestController
11+
@RequestMapping
12+
public class App230Controller {
13+
14+
@PostMapping("/")
15+
public String swaggerTest(@App230RequestBody MyRequest myRequest) {
16+
return null;
17+
}
18+
19+
public record MyRequest(int id) {
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package test.org.springdoc.api.v30.app230;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
7+
import io.swagger.v3.oas.annotations.parameters.RequestBody;
8+
9+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
10+
import static java.lang.annotation.ElementType.METHOD;
11+
import static java.lang.annotation.ElementType.PARAMETER;
12+
13+
/**
14+
* @author edudar
15+
*/
16+
@Target({PARAMETER, METHOD, ANNOTATION_TYPE})
17+
@Retention(RetentionPolicy.RUNTIME)
18+
@RequestBody(required = true)
19+
@interface App230RequestBody {
20+
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * *
7+
* * * * * * Copyright 2019-2024 the original author or authors.
8+
* * * * * *
9+
* * * * * * Licensed under the Apache License, Version 2.0 (the "License");
10+
* * * * * * you may not use this file except in compliance with the License.
11+
* * * * * * You may obtain a copy of the License at
12+
* * * * * *
13+
* * * * * * https://www.apache.org/licenses/LICENSE-2.0
14+
* * * * * *
15+
* * * * * * Unless required by applicable law or agreed to in writing, software
16+
* * * * * * distributed under the License is distributed on an "AS IS" BASIS,
17+
* * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* * * * * * See the License for the specific language governing permissions and
19+
* * * * * * limitations under the License.
20+
* * * * *
21+
* * * *
22+
* * *
23+
* *
24+
*
25+
*/
26+
27+
package test.org.springdoc.api.v30.app230;
28+
29+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
30+
31+
import org.springframework.boot.autoconfigure.SpringBootApplication;
32+
33+
/**
34+
* @author edudar
35+
*/
36+
public class SpringDocApp230Test extends AbstractSpringDocV30Test {
37+
38+
@SpringBootApplication
39+
static class SpringDocTestApp {}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/": {
15+
"post": {
16+
"tags": [
17+
"app-230-controller"
18+
],
19+
"operationId": "swaggerTest",
20+
"requestBody": {
21+
"content": {
22+
"application/json": {
23+
"schema": {
24+
"$ref": "#/components/schemas/MyRequest"
25+
}
26+
}
27+
},
28+
"required": true
29+
},
30+
"responses": {
31+
"200": {
32+
"description": "OK",
33+
"content": {
34+
"*/*": {
35+
"schema": {
36+
"type": "string"
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
}
44+
},
45+
"components": {
46+
"schemas": {
47+
"MyRequest": {
48+
"properties": {
49+
"id": {
50+
"format": "int32",
51+
"type": "integer"
52+
}
53+
},
54+
"type": "object"
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)