Skip to content

Commit 3c664d1

Browse files
jaimesfjaimesf-santaluciawing328
authored
[java] [spring] Fix multipart optional params error compilation using delegates (#20793)
* fix spring multipart optional parameters * use optional only in not required params * remove debug line --------- Co-authored-by: Jaime Sanchez <[email protected]> Co-authored-by: William Cheng <[email protected]>
1 parent 76540e5 commit 3c664d1

File tree

6 files changed

+125
-19
lines changed

6 files changed

+125
-19
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}{{#isArray}}@RequestPart{{/isArray}}{{^isArray}}{{#reactive}}@RequestPart{{/reactive}}{{^reactive}}@RequestParam{{/reactive}}{{/isArray}}{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}} {{paramName}}{{/isFile}}{{/isFormParam}}
1+
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}{{#isArray}}@RequestPart{{/isArray}}{{^isArray}}{{#reactive}}@RequestPart{{/reactive}}{{^reactive}}@RequestParam{{/reactive}}{{/isArray}}{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{^required}}{{#useOptional}}Optional<{{/useOptional}}{{/required}}{{{dataType}}}{{^required}}{{#useOptional}}>{{/useOptional}}{{/required}} {{paramName}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}} {{paramName}}{{/isFile}}{{/isFormParam}}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5384,6 +5384,37 @@ public void testEnumWithImplements() {
53845384
JavaFileAssert.assertThat(files.get("Type.java")).fileContains("Type implements java.io.Serializable {");
53855385
}
53865386

5387+
@Test
5388+
public void givenMultipartForm_whenGenerateUsingOptional_thenParameterAreCreatedAsOptional() throws IOException {
5389+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
5390+
output.deleteOnExit();
5391+
String outputPath = output.getAbsolutePath().replace('\\', '/');
5392+
5393+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/spring/issue_9530.yaml");
5394+
final SpringCodegen codegen = new SpringCodegen();
5395+
codegen.additionalProperties().put(INTERFACE_ONLY, "true");
5396+
codegen.additionalProperties().put(SpringCodegen.USE_OPTIONAL, "true");
5397+
codegen.setOpenAPI(openAPI);
5398+
codegen.setOutputDir(output.getAbsolutePath());
5399+
5400+
ClientOptInput input = new ClientOptInput();
5401+
input.openAPI(openAPI);
5402+
input.config(codegen);
5403+
5404+
5405+
DefaultGenerator generator = new DefaultGenerator();
5406+
generator.setGenerateMetadata(false);
5407+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
5408+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
5409+
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
5410+
5411+
generator.opts(input).generate();
5412+
5413+
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/PetApi.java"),
5414+
"@Valid @RequestParam(value = \"additionalMetadata\", required = false) Optional<String> additionalMetadata",
5415+
"@Valid @RequestParam(value = \"length\", required = true) Integer length");
5416+
}
5417+
53875418
@Test
53885419
public void shouldEnableBuiltInValidationOptionWhenSetToTrue() throws IOException {
53895420
final SpringCodegen codegen = new SpringCodegen();
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
openapi: 3.0.1
2+
info:
3+
version: "1.0.0"
4+
title: use-optional-multipart-spring-boot-request-body-issue
5+
paths:
6+
/pet/{petId}/uploadImage:
7+
post:
8+
tags:
9+
- pet tag
10+
summary: uploads an image
11+
operationId: uploadFile
12+
parameters:
13+
- name: petId
14+
in: path
15+
description: ID of pet to update
16+
required: true
17+
schema:
18+
type: integer
19+
format: int64
20+
requestBody:
21+
content:
22+
multipart/form-data:
23+
schema:
24+
required:
25+
- length
26+
properties:
27+
additionalMetadata:
28+
type: string
29+
description: Additional data to pass to server
30+
length:
31+
type: integer
32+
description: Content length
33+
file:
34+
type: string
35+
description: file to upload
36+
format: binary
37+
responses:
38+
200:
39+
description: successful operation
40+
content:
41+
application/json:
42+
schema:
43+
$ref: '#/components/schemas/ApiResponse'
44+
security:
45+
- petstore_auth:
46+
- write:pets
47+
- read:pets
48+
components:
49+
schemas:
50+
ApiResponse:
51+
title: An uploaded response
52+
type: object
53+
properties:
54+
code:
55+
type: integer
56+
format: int32
57+
type:
58+
type: string
59+
message:
60+
type: string
61+
description: Describes the result of uploading an image resource
62+
securitySchemes:
63+
petstore_auth:
64+
type: oauth2
65+
flows:
66+
implicit:
67+
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
68+
scopes:
69+
write:pets: modify pets in your account
70+
read:pets: read your pets
71+
api_key:
72+
type: apiKey
73+
name: api_key
74+
in: header
75+

samples/openapi3/client/petstore/spring-cloud-3-with-optional/src/main/java/org/openapitools/api/PetApi.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ ResponseEntity<Pet> updatePet(
166166

167167
ResponseEntity<Void> updatePetWithForm(
168168
@PathVariable("petId") Long petId,
169-
@Valid @RequestParam(value = "name", required = false) String name,
170-
@Valid @RequestParam(value = "status", required = false) String status
169+
@Valid @RequestParam(value = "name", required = false) Optional<String> name,
170+
@Valid @RequestParam(value = "status", required = false) Optional<String> status
171171
);
172172

173173

@@ -189,7 +189,7 @@ ResponseEntity<Void> updatePetWithForm(
189189

190190
ResponseEntity<ModelApiResponse> uploadFile(
191191
@PathVariable("petId") Long petId,
192-
@Valid @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata,
192+
@Valid @RequestParam(value = "additionalMetadata", required = false) Optional<String> additionalMetadata,
193193
@RequestPart(value = "file", required = false) MultipartFile file
194194
);
195195

samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/FakeApi.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -396,16 +396,16 @@ default ResponseEntity<Void> testEndpointParameters(
396396
@ApiParam(value = "None", required = true) @Valid @RequestParam(value = "double", required = true) Double _double,
397397
@ApiParam(value = "None", required = true) @Valid @RequestParam(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,
398398
@ApiParam(value = "None", required = true) @Valid @RequestParam(value = "byte", required = true) byte[] _byte,
399-
@ApiParam(value = "None") @Valid @RequestParam(value = "integer", required = false) Integer integer,
400-
@ApiParam(value = "None") @Valid @RequestParam(value = "int32", required = false) Integer int32,
401-
@ApiParam(value = "None") @Valid @RequestParam(value = "int64", required = false) Long int64,
402-
@ApiParam(value = "None") @Valid @RequestParam(value = "float", required = false) Float _float,
403-
@ApiParam(value = "None") @Valid @RequestParam(value = "string", required = false) String string,
399+
@ApiParam(value = "None") @Valid @RequestParam(value = "integer", required = false) Optional<Integer> integer,
400+
@ApiParam(value = "None") @Valid @RequestParam(value = "int32", required = false) Optional<Integer> int32,
401+
@ApiParam(value = "None") @Valid @RequestParam(value = "int64", required = false) Optional<Long> int64,
402+
@ApiParam(value = "None") @Valid @RequestParam(value = "float", required = false) Optional<Float> _float,
403+
@ApiParam(value = "None") @Valid @RequestParam(value = "string", required = false) Optional<String> string,
404404
@ApiParam(value = "None") @RequestPart(value = "binary", required = false) MultipartFile binary,
405-
@ApiParam(value = "None") @Valid @RequestParam(value = "date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
406-
@ApiParam(value = "None") @Valid @RequestParam(value = "dateTime", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime dateTime,
407-
@ApiParam(value = "None") @Valid @RequestParam(value = "password", required = false) String password,
408-
@ApiParam(value = "None") @Valid @RequestParam(value = "callback", required = false) String paramCallback
405+
@ApiParam(value = "None") @Valid @RequestParam(value = "date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Optional<LocalDate> date,
406+
@ApiParam(value = "None") @Valid @RequestParam(value = "dateTime", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Optional<OffsetDateTime> dateTime,
407+
@ApiParam(value = "None") @Valid @RequestParam(value = "password", required = false) Optional<String> password,
408+
@ApiParam(value = "None") @Valid @RequestParam(value = "callback", required = false) Optional<String> paramCallback
409409
) {
410410
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
411411

@@ -450,8 +450,8 @@ default ResponseEntity<Void> testEnumParameters(
450450
@ApiParam(value = "Query parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @Valid @RequestParam(value = "enum_query_string", required = false, defaultValue = "-efg") Optional<String> enumQueryString,
451451
@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1, -2") @Valid @RequestParam(value = "enum_query_integer", required = false) Optional<Integer> enumQueryInteger,
452452
@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1.1, -1.2") @Valid @RequestParam(value = "enum_query_double", required = false) Optional<Double> enumQueryDouble,
453-
@ApiParam(value = "Form parameter enum test (string array)", allowableValues = ">, $", defaultValue = "$") @Valid @RequestPart(value = "enum_form_string_array", required = false) List<String> enumFormStringArray,
454-
@ApiParam(value = "Form parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @Valid @RequestParam(value = "enum_form_string", required = false) String enumFormString
453+
@ApiParam(value = "Form parameter enum test (string array)", allowableValues = ">, $", defaultValue = "$") @Valid @RequestPart(value = "enum_form_string_array", required = false) Optional<List<String>> enumFormStringArray,
454+
@ApiParam(value = "Form parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @Valid @RequestParam(value = "enum_form_string", required = false) Optional<String> enumFormString
455455
) {
456456
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
457457

@@ -698,7 +698,7 @@ default ResponseEntity<Integer> testWithResultExample(
698698
default ResponseEntity<ModelApiResponse> uploadFileWithRequiredFile(
699699
@ApiParam(value = "ID of pet to update", required = true) @PathVariable("petId") Long petId,
700700
@ApiParam(value = "file to upload", required = true) @RequestPart(value = "requiredFile", required = true) MultipartFile requiredFile,
701-
@ApiParam(value = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata
701+
@ApiParam(value = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) Optional<String> additionalMetadata
702702
) {
703703
getRequest().ifPresent(request -> {
704704
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {

samples/server/petstore/springboot-useoptional/src/main/java/org/openapitools/api/PetApi.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ default ResponseEntity<Void> updatePet(
346346

347347
default ResponseEntity<Void> updatePetWithForm(
348348
@ApiParam(value = "ID of pet that needs to be updated", required = true) @PathVariable("petId") Long petId,
349-
@ApiParam(value = "Updated name of the pet") @Valid @RequestParam(value = "name", required = false) String name,
350-
@ApiParam(value = "Updated status of the pet") @Valid @RequestParam(value = "status", required = false) String status
349+
@ApiParam(value = "Updated name of the pet") @Valid @RequestParam(value = "name", required = false) Optional<String> name,
350+
@ApiParam(value = "Updated status of the pet") @Valid @RequestParam(value = "status", required = false) Optional<String> status
351351
) {
352352
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
353353

@@ -388,7 +388,7 @@ default ResponseEntity<Void> updatePetWithForm(
388388

389389
default ResponseEntity<ModelApiResponse> uploadFile(
390390
@ApiParam(value = "ID of pet to update", required = true) @PathVariable("petId") Long petId,
391-
@ApiParam(value = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata,
391+
@ApiParam(value = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) Optional<String> additionalMetadata,
392392
@ApiParam(value = "file to upload") @RequestPart(value = "file", required = false) MultipartFile file
393393
) {
394394
getRequest().ifPresent(request -> {

0 commit comments

Comments
 (0)