Skip to content

Commit b52f491

Browse files
committed
Default value for List/Array RequestParameter has wrong type. Fixes #1015.
1 parent 8ff850f commit b52f491

File tree

20 files changed

+279
-38
lines changed

20 files changed

+279
-38
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import javax.validation.constraints.Size;
4545

4646
import com.fasterxml.jackson.annotation.JsonView;
47+
import io.swagger.v3.core.util.PrimitiveType;
4748
import io.swagger.v3.oas.annotations.enums.ParameterIn;
4849
import io.swagger.v3.oas.models.Components;
4950
import io.swagger.v3.oas.models.OpenAPI;
@@ -460,8 +461,17 @@ private Parameter buildParam(ParameterInfo parameterInfo, Components components,
460461
if (parameter.getSchema() == null && parameter.getContent() == null) {
461462
Schema<?> schema = parameterBuilder.calculateSchema(components, parameterInfo, null,
462463
jsonView);
463-
if (parameterInfo.getDefaultValue() != null && schema !=null)
464-
schema.setDefault(parameterInfo.getDefaultValue());
464+
if (parameterInfo.getDefaultValue() != null && schema != null) {
465+
Object defaultValue = parameterInfo.getDefaultValue();
466+
// Cast default value
467+
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(schema.getType(), schema.getFormat());
468+
if (primitiveType != null) {
469+
Schema<?> primitiveSchema = primitiveType.createProperty();
470+
primitiveSchema.setDefault(parameterInfo.getDefaultValue());
471+
defaultValue = primitiveSchema.getDefault();
472+
}
473+
schema.setDefault(defaultValue);
474+
}
465475
parameter.setSchema(schema);
466476
}
467477
return parameter;

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

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.fasterxml.jackson.annotation.JsonView;
3535
import io.swagger.v3.core.util.AnnotationsUtils;
3636
import io.swagger.v3.core.util.Json;
37+
import io.swagger.v3.core.util.PrimitiveType;
3738
import io.swagger.v3.oas.annotations.enums.Explode;
3839
import io.swagger.v3.oas.annotations.media.ExampleObject;
3940
import io.swagger.v3.oas.models.Components;
@@ -49,6 +50,9 @@
4950
import org.slf4j.LoggerFactory;
5051
import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer;
5152

53+
import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters;
54+
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
55+
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties.Format;
5256
import org.springframework.core.MethodParameter;
5357
import org.springframework.core.ResolvableType;
5458
import org.springframework.core.io.Resource;
@@ -71,6 +75,11 @@ public class GenericParameterService {
7175
*/
7276
private final Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer;
7377

78+
/**
79+
* The Web conversion service.
80+
*/
81+
private final WebConversionService webConversionService;
82+
7483
/**
7584
* The constant LOGGER.
7685
*/
@@ -88,13 +97,20 @@ public class GenericParameterService {
8897

8998
/**
9099
* Instantiates a new Generic parameter builder.
91-
*
92100
* @param propertyResolverUtils the property resolver utils
93101
* @param optionalDelegatingMethodParameterCustomizer the optional delegating method parameter customizer
102+
* @param webConversionServiceOptional the web conversion service optional
94103
*/
95-
public GenericParameterService(PropertyResolverUtils propertyResolverUtils, Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer) {
104+
public GenericParameterService(PropertyResolverUtils propertyResolverUtils, Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer, Optional<WebConversionService> webConversionServiceOptional) {
96105
this.propertyResolverUtils = propertyResolverUtils;
97-
this.optionalDelegatingMethodParameterCustomizer=optionalDelegatingMethodParameterCustomizer;
106+
this.optionalDelegatingMethodParameterCustomizer = optionalDelegatingMethodParameterCustomizer;
107+
if (webConversionServiceOptional.isPresent())
108+
this.webConversionService = webConversionServiceOptional.get();
109+
else {
110+
final Format format = new Format();
111+
this.webConversionService = new WebConversionService(new DateTimeFormatters()
112+
.dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
113+
}
98114
}
99115

100116
/**
@@ -256,6 +272,16 @@ private void setSchema(io.swagger.v3.oas.annotations.Parameter parameterDoc, Com
256272
if (schema == null) {
257273
schema = AnnotationsUtils.getArraySchema(parameterDoc.array(), components, jsonView).orElse(null);
258274
}
275+
// Cast default value
276+
if (schema != null && schema.getDefault() != null) {
277+
PrimitiveType primitiveType = PrimitiveType.fromTypeAndFormat(schema.getType(), schema.getFormat());
278+
if (primitiveType != null) {
279+
Schema<?> primitiveSchema = primitiveType.createProperty();
280+
primitiveSchema.setDefault(schema.getDefault());
281+
schema.setDefault(primitiveSchema.getDefault());
282+
}
283+
}
284+
259285
parameter.setSchema(schema);
260286
}
261287
}
@@ -460,4 +486,14 @@ else if (type instanceof WildcardType) {
460486
public PropertyResolverUtils getPropertyResolverUtils() {
461487
return propertyResolverUtils;
462488
}
489+
490+
491+
/**
492+
* Gets web conversion service.
493+
*
494+
* @return the web conversion service
495+
*/
496+
public WebConversionService getWebConversionService() {
497+
return webConversionService;
498+
}
463499
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
import io.swagger.v3.oas.annotations.enums.ParameterIn;
2626
import org.apache.commons.lang3.StringUtils;
2727

28+
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
2829
import org.springframework.core.MethodParameter;
2930
import org.springframework.web.bind.annotation.CookieValue;
3031
import org.springframework.web.bind.annotation.PathVariable;
3132
import org.springframework.web.bind.annotation.RequestHeader;
3233
import org.springframework.web.bind.annotation.RequestParam;
34+
import org.springframework.web.bind.annotation.ValueConstants;
3335

3436
/**
3537
* The type Parameter info.
@@ -60,7 +62,7 @@ public class ParameterInfo {
6062
/**
6163
* The Default value.
6264
*/
63-
private String defaultValue;
65+
private Object defaultValue;
6466

6567
/**
6668
* The Param type.
@@ -97,8 +99,11 @@ else if (cookieValue != null)
9799

98100
if (StringUtils.isNotBlank(this.pName))
99101
this.pName = propertyResolverUtils.resolve(this.pName);
100-
if (StringUtils.isNotBlank(this.defaultValue))
101-
this.defaultValue = propertyResolverUtils.resolve(this.defaultValue);
102+
if (this.defaultValue !=null && !ValueConstants.DEFAULT_NONE.equals(this.defaultValue.toString())){
103+
this.defaultValue = propertyResolverUtils.resolve(this.defaultValue.toString());
104+
WebConversionService conversionService = parameterBuilder.getWebConversionService();
105+
this.defaultValue= conversionService.convert(this.defaultValue, methodParameter.getParameterType());
106+
}
102107

103108
this.required = this.required && !methodParameter.isOptional();
104109
}
@@ -171,7 +176,7 @@ public boolean isRequired() {
171176
*
172177
* @return the default value
173178
*/
174-
public String getDefaultValue() {
179+
public Object getDefaultValue() {
175180
return defaultValue;
176181
}
177182

@@ -207,7 +212,7 @@ public void setRequired(boolean required) {
207212
*
208213
* @param defaultValue the default value
209214
*/
210-
public void setDefaultValue(String defaultValue) {
215+
public void setDefaultValue(Object defaultValue) {
211216
this.defaultValue = defaultValue;
212217
}
213218

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public static Schema resolveSchemaFromType(Class<?> schemaImplementation, Compon
106106
*/
107107
public static Schema extractSchema(Components components, Type returnType, JsonView jsonView, Annotation[] annotations) {
108108
Schema schemaN = null;
109-
ResolvedSchema resolvedSchema = null;
109+
ResolvedSchema resolvedSchema;
110110
try {
111111
resolvedSchema = ModelConverters.getInstance()
112112
.resolveAsResolvedSchema(

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
6060
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
6161
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
62+
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
6263
import org.springframework.context.ApplicationContext;
6364
import org.springframework.context.annotation.Bean;
6465
import org.springframework.context.annotation.Conditional;
@@ -281,12 +282,15 @@ ReturnTypeParser genericReturnTypeParser() {
281282
*
282283
* @param propertyResolverUtils the property resolver utils
283284
* @param optionalDelegatingMethodParameterCustomizer the optional delegating method parameter customizer
285+
* @param webConversionServiceOptional the web conversion service
284286
* @return the generic parameter builder
285287
*/
286288
@Bean
287289
@ConditionalOnMissingBean
288-
GenericParameterService parameterBuilder(PropertyResolverUtils propertyResolverUtils, Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer) {
289-
return new GenericParameterService(propertyResolverUtils,optionalDelegatingMethodParameterCustomizer);
290+
GenericParameterService parameterBuilder(PropertyResolverUtils propertyResolverUtils,
291+
Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer,
292+
Optional<WebConversionService> webConversionServiceOptional) {
293+
return new GenericParameterService(propertyResolverUtils,optionalDelegatingMethodParameterCustomizer, webConversionServiceOptional);
290294
}
291295

292296
/**

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/customisers/QuerydslPredicateOperationCustomizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ private io.swagger.v3.oas.models.parameters.Parameter buildParam(Type type, Stri
275275
}
276276

277277
if (parameter.getSchema() == null) {
278-
Schema<?> schema = null;
278+
Schema<?> schema ;
279279
PrimitiveType primitiveType = PrimitiveType.fromType(type);
280280
if (primitiveType != null) {
281281
schema = primitiveType.createProperty();

springdoc-openapi-data-rest/src/test/resources/results/app10.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@
585585
"schema": {
586586
"minimum": 0,
587587
"type": "integer",
588-
"default": "0"
588+
"default": 0
589589
}
590590
},
591591
{
@@ -596,7 +596,7 @@
596596
"schema": {
597597
"minimum": 1,
598598
"type": "integer",
599-
"default": "20"
599+
"default": 20
600600
}
601601
},
602602
{

springdoc-openapi-data-rest/src/test/resources/results/app11.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"schema": {
2828
"minimum": 0,
2929
"type": "integer",
30-
"default": "0"
30+
"default": 0
3131
}
3232
},
3333
{
@@ -38,7 +38,7 @@
3838
"schema": {
3939
"minimum": 1,
4040
"type": "integer",
41-
"default": "20"
41+
"default": 20
4242
}
4343
},
4444
{

springdoc-openapi-data-rest/src/test/resources/results/app13.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"schema": {
2727
"minimum": 0,
2828
"type": "integer",
29-
"default": "0"
29+
"default": 0
3030
}
3131
},
3232
{
@@ -37,7 +37,7 @@
3737
"schema": {
3838
"minimum": 1,
3939
"type": "integer",
40-
"default": "5"
40+
"default": 5
4141
}
4242
},
4343
{

springdoc-openapi-data-rest/src/test/resources/results/app14.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"schema": {
2727
"minimum": 0,
2828
"type": "integer",
29-
"default": "0"
29+
"default": 0
3030
}
3131
},
3232
{
@@ -37,7 +37,7 @@
3737
"schema": {
3838
"minimum": 1,
3939
"type": "integer",
40-
"default": "25"
40+
"default": 25
4141
}
4242
},
4343
{

0 commit comments

Comments
 (0)