Skip to content

Commit ae2b693

Browse files
authored
[BUG] Failed to add required=false (#2062) (#5573)
1 parent f03458d commit ae2b693

File tree

32 files changed

+123
-89
lines changed

32 files changed

+123
-89
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isFormParam}}{{^isFile}}@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}}) @RequestPart(value="{{baseName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}}@ApiParam(value = "{{{description}}}") {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart(value = "{{baseName}}") {{#isListContainer}}List<{{/isListContainer}}MultipartFile{{#isListContainer}}>{{/isListContainer}} {{baseName}}{{/isFile}}{{/isFormParam}}
1+
{{#isFormParam}}{{^isFile}}@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}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}}@ApiParam(value = "{{{description}}}") {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isListContainer}}List<{{/isListContainer}}MultipartFile{{#isListContainer}}>{{/isListContainer}} {{baseName}}{{/isFile}}{{/isFormParam}}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public void testMultipartBoot() throws IOException {
282282
final String multipartArrayApi = files.get("/src/main/java/org/openapitools/api/MultipartArrayApi.java");
283283
Assert.assertTrue(multipartArrayApi.contains("List<MultipartFile> files"));
284284
Assert.assertTrue(multipartArrayApi.contains("@ApiParam(value = \"Many files\")"));
285-
Assert.assertTrue(multipartArrayApi.contains("@RequestPart(value = \"files\")"));
285+
Assert.assertTrue(multipartArrayApi.contains("@RequestPart(value = \"files\", required = false)"));
286286

287287
// Check that the delegate handles the single file
288288
final String multipartSingleApiDelegate = files.get("/src/main/java/org/openapitools/api/MultipartSingleApiDelegate.java");
@@ -292,7 +292,14 @@ public void testMultipartBoot() throws IOException {
292292
final String multipartSingleApi = files.get("/src/main/java/org/openapitools/api/MultipartSingleApi.java");
293293
Assert.assertTrue(multipartSingleApi.contains("MultipartFile file"));
294294
Assert.assertTrue(multipartSingleApi.contains("@ApiParam(value = \"One file\")"));
295-
Assert.assertTrue(multipartSingleApi.contains("@RequestPart(value = \"file\")"));
295+
Assert.assertTrue(multipartSingleApi.contains("@RequestPart(value = \"file\", required = false)"));
296+
297+
// Check that api validates mixed multipart request
298+
final String multipartMixedApi = files.get("/src/main/java/org/openapitools/api/MultipartMixedApi.java");
299+
Assert.assertTrue(multipartMixedApi.contains("MultipartFile file"));
300+
Assert.assertTrue(multipartMixedApi.contains("@RequestPart(value = \"file\", required = true)"));
301+
System.out.println(multipartMixedApi);
302+
Assert.assertTrue(multipartMixedApi.contains("@Valid @RequestPart(value = \"marker\", required = false)"));
296303
}
297304

298305
@Test

modules/openapi-generator/src/test/resources/3_0/form-multipart-binary-array.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,33 @@ paths:
4040
description: "One file"
4141
type: string
4242
format: binary
43+
responses:
44+
'204':
45+
description: Successful operation
46+
/multipart-mixed:
47+
post:
48+
tags:
49+
- multipart
50+
description: Mixed MultipartFile test
51+
operationId: multipartMixed
52+
requestBody:
53+
content:
54+
multipart/form-data:
55+
schema:
56+
type: object
57+
required:
58+
- file
59+
properties:
60+
marker:
61+
description: "additional object"
62+
type: object
63+
properties:
64+
name:
65+
type: string
66+
file:
67+
description: "a file"
68+
type: string
69+
format: binary
4370
responses:
4471
'204':
4572
description: Successful operation

samples/client/petstore/spring-stubs/src/main/java/org/openapitools/api/PetApi.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ default ResponseEntity<Void> updatePet(@ApiParam(value = "Pet object that needs
250250
@RequestMapping(value = "/pet/{petId}",
251251
consumes = "application/x-www-form-urlencoded",
252252
method = RequestMethod.POST)
253-
default ResponseEntity<Void> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,@ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status) {
253+
default ResponseEntity<Void> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @Valid @RequestPart(value = "name", required = false) String name,@ApiParam(value = "Updated status of the pet") @Valid @RequestPart(value = "status", required = false) String status) {
254254
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
255255

256256
}
@@ -276,7 +276,7 @@ default ResponseEntity<Void> updatePetWithForm(@ApiParam(value = "ID of pet that
276276
produces = "application/json",
277277
consumes = "multipart/form-data",
278278
method = RequestMethod.POST)
279-
default ResponseEntity<ModelApiResponse> uploadFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "file") MultipartFile file) {
279+
default ResponseEntity<ModelApiResponse> uploadFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @Valid @RequestPart(value = "additionalMetadata", required = false) String additionalMetadata,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "file", required = false) MultipartFile file) {
280280
getRequest().ifPresent(request -> {
281281
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
282282
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {

samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/FakeApi.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ default CompletableFuture<ResponseEntity<Client>> testClientModel(@ApiParam(valu
252252
@RequestMapping(value = "/fake",
253253
consumes = { "application/x-www-form-urlencoded" },
254254
method = RequestMethod.POST)
255-
default CompletableFuture<ResponseEntity<Void>> testEndpointParameters(@ApiParam(value = "None", required=true) @RequestPart(value="number", required=true) BigDecimal number,@ApiParam(value = "None", required=true) @RequestPart(value="double", required=true) Double _double,@ApiParam(value = "None", required=true) @RequestPart(value="pattern_without_delimiter", required=true) String patternWithoutDelimiter,@ApiParam(value = "None", required=true) @RequestPart(value="byte", required=true) byte[] _byte,@ApiParam(value = "None") @RequestPart(value="integer", required=false) Integer integer,@ApiParam(value = "None") @RequestPart(value="int32", required=false) Integer int32,@ApiParam(value = "None") @RequestPart(value="int64", required=false) Long int64,@ApiParam(value = "None") @RequestPart(value="float", required=false) Float _float,@ApiParam(value = "None") @RequestPart(value="string", required=false) String string,@ApiParam(value = "None") @Valid @RequestPart(value = "binary") MultipartFile binary,@ApiParam(value = "None") @RequestPart(value="date", required=false) LocalDate date,@ApiParam(value = "None") @RequestPart(value="dateTime", required=false) OffsetDateTime dateTime,@ApiParam(value = "None") @RequestPart(value="password", required=false) String password,@ApiParam(value = "None") @RequestPart(value="callback", required=false) String paramCallback) {
255+
default CompletableFuture<ResponseEntity<Void>> testEndpointParameters(@ApiParam(value = "None", required=true) @Valid @RequestPart(value = "number", required = true) BigDecimal number,@ApiParam(value = "None", required=true) @Valid @RequestPart(value = "double", required = true) Double _double,@ApiParam(value = "None", required=true) @Valid @RequestPart(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,@ApiParam(value = "None", required=true) @Valid @RequestPart(value = "byte", required = true) byte[] _byte,@ApiParam(value = "None") @Valid @RequestPart(value = "integer", required = false) Integer integer,@ApiParam(value = "None") @Valid @RequestPart(value = "int32", required = false) Integer int32,@ApiParam(value = "None") @Valid @RequestPart(value = "int64", required = false) Long int64,@ApiParam(value = "None") @Valid @RequestPart(value = "float", required = false) Float _float,@ApiParam(value = "None") @Valid @RequestPart(value = "string", required = false) String string,@ApiParam(value = "None") @Valid @RequestPart(value = "binary", required = false) MultipartFile binary,@ApiParam(value = "None") @Valid @RequestPart(value = "date", required = false) LocalDate date,@ApiParam(value = "None") @Valid @RequestPart(value = "dateTime", required = false) OffsetDateTime dateTime,@ApiParam(value = "None") @Valid @RequestPart(value = "password", required = false) String password,@ApiParam(value = "None") @Valid @RequestPart(value = "callback", required = false) String paramCallback) {
256256
return CompletableFuture.completedFuture(new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED));
257257

258258
}
@@ -280,7 +280,7 @@ default CompletableFuture<ResponseEntity<Void>> testEndpointParameters(@ApiParam
280280
@RequestMapping(value = "/fake",
281281
consumes = { "application/x-www-form-urlencoded" },
282282
method = RequestMethod.GET)
283-
default CompletableFuture<ResponseEntity<Void>> testEnumParameters(@ApiParam(value = "Header parameter enum test (string array)" , allowableValues=">, $") @RequestHeader(value="enum_header_string_array", required=false) List<String> enumHeaderStringArray,@ApiParam(value = "Header parameter enum test (string)" , allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestHeader(value="enum_header_string", required=false) String enumHeaderString,@ApiParam(value = "Query parameter enum test (string array)", allowableValues = ">, $") @Valid @RequestParam(value = "enum_query_string_array", required = false) List<String> enumQueryStringArray,@ApiParam(value = "Query parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @Valid @RequestParam(value = "enum_query_string", required = false, defaultValue="-efg") String enumQueryString,@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1, -2") @Valid @RequestParam(value = "enum_query_integer", required = false) Integer enumQueryInteger,@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1.1, -1.2") @Valid @RequestParam(value = "enum_query_double", required = false) Double enumQueryDouble,@ApiParam(value = "Form parameter enum test (string array)", allowableValues=">, $") @RequestPart(value="enum_form_string_array", required=false) List<String> enumFormStringArray,@ApiParam(value = "Form parameter enum test (string)", allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestPart(value="enum_form_string", required=false) String enumFormString) {
283+
default CompletableFuture<ResponseEntity<Void>> testEnumParameters(@ApiParam(value = "Header parameter enum test (string array)" , allowableValues=">, $") @RequestHeader(value="enum_header_string_array", required=false) List<String> enumHeaderStringArray,@ApiParam(value = "Header parameter enum test (string)" , allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestHeader(value="enum_header_string", required=false) String enumHeaderString,@ApiParam(value = "Query parameter enum test (string array)", allowableValues = ">, $") @Valid @RequestParam(value = "enum_query_string_array", required = false) List<String> enumQueryStringArray,@ApiParam(value = "Query parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @Valid @RequestParam(value = "enum_query_string", required = false, defaultValue="-efg") String enumQueryString,@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1, -2") @Valid @RequestParam(value = "enum_query_integer", required = false) Integer enumQueryInteger,@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1.1, -1.2") @Valid @RequestParam(value = "enum_query_double", required = false) Double enumQueryDouble,@ApiParam(value = "Form parameter enum test (string array)", allowableValues=">, $") @Valid @RequestPart(value = "enum_form_string_array", required = false) List<String> enumFormStringArray,@ApiParam(value = "Form parameter enum test (string)", allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @Valid @RequestPart(value = "enum_form_string", required = false) String enumFormString) {
284284
return CompletableFuture.completedFuture(new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED));
285285

286286
}
@@ -340,7 +340,7 @@ default CompletableFuture<ResponseEntity<Void>> testInlineAdditionalProperties(@
340340
@RequestMapping(value = "/fake/jsonFormData",
341341
consumes = { "application/x-www-form-urlencoded" },
342342
method = RequestMethod.GET)
343-
default CompletableFuture<ResponseEntity<Void>> testJsonFormData(@ApiParam(value = "field1", required=true) @RequestPart(value="param", required=true) String param,@ApiParam(value = "field2", required=true) @RequestPart(value="param2", required=true) String param2) {
343+
default CompletableFuture<ResponseEntity<Void>> testJsonFormData(@ApiParam(value = "field1", required=true) @Valid @RequestPart(value = "param", required = true) String param,@ApiParam(value = "field2", required=true) @Valid @RequestPart(value = "param2", required = true) String param2) {
344344
return CompletableFuture.completedFuture(new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED));
345345

346346
}
@@ -388,7 +388,7 @@ default CompletableFuture<ResponseEntity<Void>> testQueryParameterCollectionForm
388388
produces = { "application/json" },
389389
consumes = { "multipart/form-data" },
390390
method = RequestMethod.POST)
391-
default CompletableFuture<ResponseEntity<ModelApiResponse>> uploadFileWithRequiredFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "requiredFile") MultipartFile requiredFile,@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata) {
391+
default CompletableFuture<ResponseEntity<ModelApiResponse>> uploadFileWithRequiredFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "requiredFile", required = true) MultipartFile requiredFile,@ApiParam(value = "Additional data to pass to server") @Valid @RequestPart(value = "additionalMetadata", required = false) String additionalMetadata) {
392392
return CompletableFuture.supplyAsync(()-> {
393393
getRequest().ifPresent(request -> {
394394
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {

samples/server/petstore/spring-mvc-j8-async/src/main/java/org/openapitools/api/PetApi.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ default CompletableFuture<ResponseEntity<Void>> updatePet(@ApiParam(value = "Pet
263263
@RequestMapping(value = "/pet/{petId}",
264264
consumes = { "application/x-www-form-urlencoded" },
265265
method = RequestMethod.POST)
266-
default CompletableFuture<ResponseEntity<Void>> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,@ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status) {
266+
default CompletableFuture<ResponseEntity<Void>> updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @Valid @RequestPart(value = "name", required = false) String name,@ApiParam(value = "Updated status of the pet") @Valid @RequestPart(value = "status", required = false) String status) {
267267
return CompletableFuture.completedFuture(new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED));
268268

269269
}
@@ -289,7 +289,7 @@ default CompletableFuture<ResponseEntity<Void>> updatePetWithForm(@ApiParam(valu
289289
produces = { "application/json" },
290290
consumes = { "multipart/form-data" },
291291
method = RequestMethod.POST)
292-
default CompletableFuture<ResponseEntity<ModelApiResponse>> uploadFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "file") MultipartFile file) {
292+
default CompletableFuture<ResponseEntity<ModelApiResponse>> uploadFile(@ApiParam(value = "ID of pet to update",required=true) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @Valid @RequestPart(value = "additionalMetadata", required = false) String additionalMetadata,@ApiParam(value = "file to upload") @Valid @RequestPart(value = "file", required = false) MultipartFile file) {
293293
return CompletableFuture.supplyAsync(()-> {
294294
getRequest().ifPresent(request -> {
295295
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {

0 commit comments

Comments
 (0)