Skip to content

Commit 4f34ab3

Browse files
author
João Dias
committed
FIx issue springdoc#351
1 parent aaf8383 commit 4f34ab3

File tree

8 files changed

+84
-14
lines changed

8 files changed

+84
-14
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractResponseBuilder.java

+30-5
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
import org.springframework.web.bind.annotation.ResponseStatus;
2424
import org.springframework.web.method.HandlerMethod;
2525

26-
import java.lang.reflect.Method;
27-
import java.lang.reflect.ParameterizedType;
28-
import java.lang.reflect.Type;
26+
import java.lang.reflect.*;
2927
import java.util.*;
3028
import java.util.stream.Collectors;
3129
import java.util.stream.Stream;
@@ -39,9 +37,12 @@ public abstract class AbstractResponseBuilder {
3937

4038
private final OperationBuilder operationBuilder;
4139

42-
protected AbstractResponseBuilder(OperationBuilder operationBuilder) {
40+
private final List<ReturnTypeParser> returnTypeParsers;
41+
42+
protected AbstractResponseBuilder(OperationBuilder operationBuilder, List<ReturnTypeParser> returnTypeParsers) {
4343
super();
4444
this.operationBuilder = operationBuilder;
45+
this.returnTypeParsers = returnTypeParsers;
4546
}
4647

4748
public ApiResponses build(Components components, HandlerMethod handlerMethod, Operation operation,
@@ -203,7 +204,7 @@ private Set<io.swagger.v3.oas.annotations.responses.ApiResponse> getApiResponses
203204

204205
private Content buildContent(Components components, Method method, String[] methodProduces, JsonView jsonView) {
205206
Content content = new Content();
206-
Type returnType = method.getGenericReturnType();
207+
Type returnType = getReturnType(method);
207208
if (isVoid(returnType)) {
208209
// if void, no content
209210
content = null;
@@ -219,6 +220,19 @@ private Content buildContent(Components components, Method method, String[] meth
219220
return content;
220221
}
221222

223+
private Type getReturnType(Method method) {
224+
Type returnType = Object.class;
225+
for (ReturnTypeParser returnTypeParser: returnTypeParsers) {
226+
if (returnType.getTypeName().equals(Object.class.getTypeName())) {
227+
returnType = returnTypeParser.getReturnType(method);
228+
} else {
229+
break;
230+
}
231+
}
232+
233+
return returnType;
234+
}
235+
222236
private Schema<?> calculateSchema(Components components, Type returnType, JsonView jsonView) {
223237
Schema<?> schemaN = null;
224238
if (isVoid(returnType)) {
@@ -328,4 +342,15 @@ private boolean isVoid(Type returnType) {
328342
return Void.TYPE.equals(returnType) || (returnType instanceof ParameterizedType
329343
&& Void.class.equals(((ParameterizedType) returnType).getActualTypeArguments()[0]));
330344
}
345+
346+
interface ReturnTypeParser {
347+
Type getReturnType(Method method);
348+
}
349+
350+
public static class GenericReturnTypeParser implements ReturnTypeParser {
351+
@Override
352+
public Type getReturnType(Method method) {
353+
return method.getGenericReturnType();
354+
}
355+
}
331356
}

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ public SecurityParser securityParser(PropertyResolverUtils propertyResolverUtils
7979
return new SecurityParser(propertyResolverUtils);
8080
}
8181

82+
@Bean
83+
public AbstractResponseBuilder.GenericReturnTypeParser genericReturnTypeParser() {
84+
return new AbstractResponseBuilder.GenericReturnTypeParser();
85+
}
86+
8287
static class ConditionOnCacheOrGroupedOpenApi extends AnyNestedCondition {
8388

8489
ConditionOnCacheOrGroupedOpenApi() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.springdoc.core;
2+
3+
import kotlin.coroutines.Continuation;
4+
import org.springdoc.core.customizers.OperationCustomizer;
5+
import org.springdoc.core.customizers.ParameterCustomizer;
6+
7+
import java.lang.reflect.*;
8+
import java.util.Arrays;
9+
import java.util.List;
10+
import java.util.Optional;
11+
12+
public class KotlinCoroutinesReturnTypeParser implements AbstractResponseBuilder.ReturnTypeParser {
13+
14+
@Override
15+
public Type getReturnType(Method method) {
16+
Type returnType = Object.class;
17+
Optional<Parameter> continuationParameter = Arrays.stream(method.getParameters())
18+
.filter((parameter) -> parameter.getType().getCanonicalName().equals(Continuation.class.getCanonicalName()))
19+
.findFirst();
20+
21+
if (continuationParameter.isPresent()) {
22+
Type continuationType = continuationParameter.get().getParameterizedType();
23+
if (continuationType instanceof ParameterizedType) {
24+
Type actualTypeArguments = ((ParameterizedType) continuationType).getActualTypeArguments()[0];
25+
if (actualTypeArguments instanceof WildcardType) {
26+
returnType = ((WildcardType) actualTypeArguments).getLowerBounds()[0];
27+
}
28+
}
29+
}
30+
31+
return returnType;
32+
}
33+
}

springdoc-openapi-kotlin/src/main/java/org/springdoc/core/SpringDocKotlinConfiguration.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ public class SpringDocKotlinConfiguration {
1818

1919
@Bean
2020
@Primary
21-
KotlinCoroutinesRequestBuilder kotlinCoroutinesRequestBuilder(AbstractParameterBuilder parameterBuilder, RequestBodyBuilder requestBodyBuilder,
21+
public KotlinCoroutinesRequestBuilder kotlinCoroutinesRequestBuilder(AbstractParameterBuilder parameterBuilder, RequestBodyBuilder requestBodyBuilder,
2222
OperationBuilder operationBuilder, Optional<List<OperationCustomizer>> operationCustomizers, Optional<List<ParameterCustomizer>> parameterCustomizers) {
2323
return new KotlinCoroutinesRequestBuilder(parameterBuilder, requestBodyBuilder,
2424
operationBuilder, operationCustomizers, parameterCustomizers);
2525
}
2626

27+
@Bean
28+
public KotlinCoroutinesReturnTypeParser kotlinCoroutinesReturnTypeParser() {
29+
return new KotlinCoroutinesReturnTypeParser();
30+
}
31+
2732

2833
}

springdoc-openapi-webflux-core/src/main/java/org/springdoc/core/ResponseBuilder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
import reactor.core.publisher.Mono;
1111

1212
import java.lang.reflect.ParameterizedType;
13+
import java.util.List;
1314

1415
@SuppressWarnings("rawtypes")
1516
public class ResponseBuilder extends AbstractResponseBuilder {
1617

17-
public ResponseBuilder(OperationBuilder operationBuilder) {
18-
super(operationBuilder);
18+
public ResponseBuilder(OperationBuilder operationBuilder, List<ReturnTypeParser> returnTypeParsers) {
19+
super(operationBuilder, returnTypeParsers);
1920
}
2021

2122
@Override

springdoc-openapi-webflux-core/src/main/java/org/springdoc/core/SpringDocWebFluxConfiguration.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public RequestBuilder requestBuilder(AbstractParameterBuilder parameterBuilder,
4646
}
4747

4848
@Bean
49-
public ResponseBuilder responseBuilder(OperationBuilder operationBuilder) {
50-
return new ResponseBuilder(operationBuilder);
49+
public ResponseBuilder responseBuilder(OperationBuilder operationBuilder, List<AbstractResponseBuilder.ReturnTypeParser> returnTypeParsers) {
50+
return new ResponseBuilder(operationBuilder, returnTypeParsers);
5151
}
5252

5353
}

springdoc-openapi-webmvc-core/src/main/java/org/springdoc/core/ResponseBuilder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88

99
import java.lang.reflect.ParameterizedType;
1010
import java.lang.reflect.Type;
11+
import java.util.List;
1112
import java.util.concurrent.Callable;
1213

1314
@SuppressWarnings("rawtypes")
1415
public class ResponseBuilder extends AbstractResponseBuilder {
1516

16-
public ResponseBuilder(OperationBuilder operationBuilder) {
17-
super(operationBuilder);
17+
public ResponseBuilder(OperationBuilder operationBuilder, List<ReturnTypeParser> returnTypeParsers) {
18+
super(operationBuilder, returnTypeParsers);
1819
}
1920

2021
@Override

springdoc-openapi-webmvc-core/src/main/java/org/springdoc/core/SpringDocWebMvcConfiguration.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public RequestBuilder requestBuilder(AbstractParameterBuilder parameterBuilder,
5555

5656
@Bean
5757
@ConditionalOnMissingBean
58-
public ResponseBuilder responseBuilder(OperationBuilder operationBuilder) {
59-
return new ResponseBuilder(operationBuilder);
58+
public ResponseBuilder responseBuilder(OperationBuilder operationBuilder, List<AbstractResponseBuilder.ReturnTypeParser> returnTypeParsers) {
59+
return new ResponseBuilder(operationBuilder, returnTypeParsers);
6060
}
6161

6262
@Configuration

0 commit comments

Comments
 (0)