Skip to content

Commit df35696

Browse files
author
bnasslahsen
committed
Support Java record for @ParameterObejct annotation. Fixes #1728
1 parent 403a44a commit df35696

File tree

4 files changed

+71
-47
lines changed

4 files changed

+71
-47
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,23 @@ private static Stream<MethodParameter> fromSimpleClass(Class<?> paramClass, Fiel
173173
Annotation[] fieldAnnotations = field.getDeclaredAnnotations();
174174
try {
175175
Parameter parameter = field.getAnnotation(Parameter.class);
176-
boolean isNotRequired = parameter == null || !parameter.required();
176+
boolean isNotRequired = parameter == null || !parameter.required();
177177
Annotation[] finalFieldAnnotations = fieldAnnotations;
178-
return Stream.of(Introspector.getBeanInfo(paramClass).getPropertyDescriptors())
179-
.filter(d -> d.getName().equals(field.getName()))
180-
.map(PropertyDescriptor::getReadMethod)
181-
.filter(Objects::nonNull)
182-
.map(method -> new MethodParameter(method, -1))
183-
.map(methodParameter -> DelegatingMethodParameter.changeContainingClass(methodParameter, paramClass))
184-
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), finalFieldAnnotations, true, isNotRequired));
178+
if (paramClass.isRecord()) {
179+
return Stream.of( paramClass.getRecordComponents()).map(recordComponent -> recordComponent.getAccessor())
180+
.map(method -> new MethodParameter(method, -1))
181+
.map(methodParameter -> DelegatingMethodParameter.changeContainingClass(methodParameter, paramClass))
182+
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), finalFieldAnnotations, true, isNotRequired));
183+
184+
}
185+
else
186+
return Stream.of(Introspector.getBeanInfo(paramClass).getPropertyDescriptors())
187+
.filter(d -> d.getName().equals(field.getName()))
188+
.map(PropertyDescriptor::getReadMethod)
189+
.filter(Objects::nonNull)
190+
.map(method -> new MethodParameter(method, -1))
191+
.map(methodParameter -> DelegatingMethodParameter.changeContainingClass(methodParameter, paramClass))
192+
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), finalFieldAnnotations, true, isNotRequired));
185193
}
186194
catch (IntrospectionException e) {
187195
return Stream.of();

springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app69/HelloController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626

2727
import java.util.concurrent.Callable;
2828

29+
import org.springdoc.core.annotations.ParameterObject;
30+
2931
import org.springframework.http.ResponseEntity;
32+
import org.springframework.web.bind.annotation.GetMapping;
3033
import org.springframework.web.bind.annotation.RequestMapping;
3134
import org.springframework.web.bind.annotation.RequestMethod;
3235
import org.springframework.web.bind.annotation.RestController;
@@ -39,4 +42,9 @@ private Callable<ResponseEntity<PersonDTO>> getTasks(String str) {
3942
return null;
4043
}
4144

45+
@GetMapping(value = "/testRecord")
46+
private Callable<ResponseEntity<PersonDTO>> getInfo(@ParameterObject PersonDTO personDTO) {
47+
return null;
48+
}
49+
4250
}

springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app69/PersonDTO.java

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,43 +24,5 @@
2424

2525
package test.org.springdoc.api.v30.app69;
2626

27-
public class PersonDTO {
28-
private String email;
29-
30-
private String firstName;
31-
32-
private String lastName;
33-
34-
public PersonDTO() {
35-
}
36-
37-
public PersonDTO(final String email, final String firstName, final String lastName) {
38-
this.email = email;
39-
this.firstName = firstName;
40-
this.lastName = lastName;
41-
}
42-
43-
public String getEmail() {
44-
return email;
45-
}
46-
47-
public void setEmail(final String email) {
48-
this.email = email;
49-
}
50-
51-
public String getFirstName() {
52-
return firstName;
53-
}
54-
55-
public void setFirstName(final String firstName) {
56-
this.firstName = firstName;
57-
}
58-
59-
public String getLastName() {
60-
return lastName;
61-
}
62-
63-
public void setLastName(final String lastName) {
64-
this.lastName = lastName;
65-
}
27+
public record PersonDTO (String email,String firstName,String lastName){
6628
}

springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app69.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,52 @@
1111
}
1212
],
1313
"paths": {
14+
"/testRecord": {
15+
"get": {
16+
"tags": [
17+
"hello-controller"
18+
],
19+
"operationId": "getInfo",
20+
"parameters": [
21+
{
22+
"name": "email",
23+
"in": "query",
24+
"required": false,
25+
"schema": {
26+
"type": "string"
27+
}
28+
},
29+
{
30+
"name": "firstName",
31+
"in": "query",
32+
"required": false,
33+
"schema": {
34+
"type": "string"
35+
}
36+
},
37+
{
38+
"name": "lastName",
39+
"in": "query",
40+
"required": false,
41+
"schema": {
42+
"type": "string"
43+
}
44+
}
45+
],
46+
"responses": {
47+
"200": {
48+
"description": "OK",
49+
"content": {
50+
"*/*": {
51+
"schema": {
52+
"$ref": "#/components/schemas/PersonDTO"
53+
}
54+
}
55+
}
56+
}
57+
}
58+
}
59+
},
1460
"/tasks": {
1561
"get": {
1662
"tags": [

0 commit comments

Comments
 (0)