Skip to content

Commit 68967b8

Browse files
peyerrogermacjohnny
authored andcommitted
BugFix #2053 Spring Boot fails to parse LocalDate query parameter (#3860)
Adds the format annotation so that Spring is able to serialize OpenApi date/date-time format into LocalDate/OffsetDateTime.
1 parent 3e6b72b commit 68967b8

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue={{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}){{/isModel}} {{>optionalDataType}} {{paramName}}{{/isQueryParam}}
1+
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue={{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/defaultValue}}{{/isContainer}}){{/isModel}}{{#isDate}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE){{/isDate}}{{#isDateTime}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME){{/isDateTime}} {{>optionalDataType}} {{paramName}}{{/isQueryParam}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

+39
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,52 @@ public void doNotGenerateRequestParamForObjectQueryParam() throws IOException {
167167
checkFileNotContains(generator, outputPath + "/src/main/java/org/openapitools/api/PonyApi.java", "@RequestParam");
168168
}
169169

170+
@Test
171+
public void generateFormatForDateAndDateTimeQueryParam() throws IOException {
172+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
173+
output.deleteOnExit();
174+
String outputPath = output.getAbsolutePath().replace('\\', '/');
175+
176+
OpenAPI openAPI = new OpenAPIParser()
177+
.readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI();
178+
179+
SpringCodegen codegen = new SpringCodegen();
180+
codegen.setOutputDir(output.getAbsolutePath());
181+
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
182+
183+
ClientOptInput input = new ClientOptInput();
184+
input.openAPI(openAPI);
185+
input.config(codegen);
186+
187+
MockDefaultGenerator generator = new MockDefaultGenerator();
188+
generator.opts(input).generate();
189+
190+
checkFileContains(
191+
generator,
192+
outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java",
193+
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)"
194+
);
195+
checkFileContains(
196+
generator,
197+
outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java",
198+
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)"
199+
);
200+
}
201+
170202
private void checkFileNotContains(MockDefaultGenerator generator, String path, String... lines) {
171203
String file = generator.getFiles().get(path);
172204
assertNotNull(file);
173205
for (String line : lines)
174206
assertFalse(file.contains(line));
175207
}
176208

209+
private void checkFileContains(MockDefaultGenerator generator, String path, String... lines) {
210+
String file = generator.getFiles().get(path);
211+
assertNotNull(file);
212+
for (String line : lines)
213+
assertTrue(file.contains(line));
214+
}
215+
177216
@Test
178217
public void clientOptsUnicity() {
179218
SpringCodegen codegen = new SpringCodegen();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
openapi: 3.0.0
2+
servers:
3+
- url: 'localhost:8080'
4+
info:
5+
version: 1.0.0
6+
title: OpenAPI Zoo
7+
license:
8+
name: Apache-2.0
9+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
10+
paths:
11+
/elephants:
12+
get:
13+
operationId: getElephants
14+
parameters:
15+
- in: query
16+
name: startDate
17+
schema:
18+
type: string
19+
format: date
20+
/zebras:
21+
get:
22+
operationId: getZebras
23+
parameters:
24+
- in: query
25+
name: startDateTime
26+
schema:
27+
type: string
28+
format: date-time

0 commit comments

Comments
 (0)