Skip to content

Commit 59bd0eb

Browse files
committed
convert byte[] to String for operation params
1 parent 59042aa commit 59bd0eb

38 files changed

Lines changed: 58 additions & 36 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ public AbstractJavaCodegen() {
290290
typeMapping.put("date", "Date");
291291
typeMapping.put("file", "File");
292292
typeMapping.put("AnyType", "Object");
293+
typeMapping.put("ByteArray", "byte[]");
293294

294295
importMapping.put("BigDecimal", "java.math.BigDecimal");
295296
importMapping.put("UUID", "java.util.UUID");

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ public void setIsVoid(boolean isVoid) {
798798

799799
prepareVersioningParameters(ops);
800800
handleImplicitHeaders(operation);
801+
convertByteArrayParamsToStringType(operation);
801802
}
802803
// The tag for the controller is the first tag of the first operation
803804
final CodegenOperation firstOperation = ops.get(0);
@@ -813,6 +814,26 @@ public void setIsVoid(boolean isVoid) {
813814
return objs;
814815
}
815816

817+
/**
818+
* Converts parameters of type {@code byte[]} (i.e., OpenAPI {@code type: string, format: byte}) to {@code String}.
819+
* <p>
820+
* In OpenAPI, {@code type: string, format: byte} is a base64-encoded string. However, Spring does not automatically
821+
* decode base64-encoded request parameters into {@code byte[]} for query, path, header, cookie, or form parameters.
822+
* Therefore, these parameters are mapped to {@code String} to avoid incorrect type handling and to ensure the
823+
* application receives the raw base64 string as provided by the client.
824+
* </p>
825+
*
826+
* @param operation the codegen operation whose parameters will be checked and converted if necessary
827+
**/
828+
private void convertByteArrayParamsToStringType(CodegenOperation operation) {
829+
var convertedParams = operation.allParams.stream()
830+
.filter(CodegenParameter::getIsByteArray)
831+
.filter(param -> param.isQueryParam || param.isPathParam || param.isHeaderParam || param.isCookieParam || param.isFormParam)
832+
.peek(param -> param.dataType = "String")
833+
.collect(Collectors.toList());
834+
LOGGER.info("Converted parameters {} from byte[] to String in operation {}", convertedParams.stream().map(param -> param.paramName), operation.operationId);
835+
}
836+
816837
private interface DataTypeAssigner {
817838
void setReturnType(String returnType);
818839

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isCookieParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}} @CookieValue(name = "{{baseName}}"{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{>dateTimeParam}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{/isCookieParam}}
1+
{{#isCookieParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}} @CookieValue(name = "{{baseName}}"{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{>dateTimeParam}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{#isByteArray}} /* base64 encoded binary */{{/isByteArray}}{{/isCookieParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} {{>beanValidationBodyParams}}@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}}) {{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}MultipartFile{{#isArray}}>{{/isArray}}{{/reactive}} {{paramName}}{{/isFile}}{{/isFormParam}}
1+
{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} {{>beanValidationBodyParams}}@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}}{{#isByteArray}} /* base64 encoded binary */{{/isByteArray}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}MultipartFile{{#isArray}}>{{/isArray}}{{/reactive}} {{paramName}}{{/isFile}}{{/isFormParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isHeaderParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}} @RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{>dateTimeParam}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
1+
{{#isHeaderParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}} @RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{>dateTimeParam}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{#isByteArray}} /* base64 encoded binary */{{/isByteArray}}{{/isHeaderParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isPathParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{>paramDoc}} @PathVariable("{{baseName}}"){{>dateTimeParam}}{{#isDeprecated}} @Deprecated{{/isDeprecated}} {{>optionalDataType}} {{paramName}}{{/isPathParam}}
1+
{{#isPathParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{>paramDoc}} @PathVariable("{{baseName}}"){{>dateTimeParam}}{{#isDeprecated}} @Deprecated{{/isDeprecated}} {{>optionalDataType}} {{paramName}}{{#isByteArray}} /* base64 encoded binary */{{/isByteArray}}{{/isPathParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isQueryParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = {{#isMap}}""{{/isMap}}{{^isMap}}"{{baseName}}"{{/isMap}}{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/isModel}}{{>dateTimeParam}}{{#isDeprecated}} @Deprecated{{/isDeprecated}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{/isQueryParam}}
1+
{{#isQueryParam}}{{#vendorExtensions.x-field-extra-annotation}}{{{.}}} {{/vendorExtensions.x-field-extra-annotation}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}}{{^isModel}} @RequestParam(value = {{#isMap}}""{{/isMap}}{{^isMap}}"{{baseName}}"{{/isMap}}{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/isModel}}{{>dateTimeParam}}{{#isDeprecated}} @Deprecated{{/isDeprecated}} {{>nullableAnnotation}}{{>optionalDataType}} {{paramName}}{{#isByteArray}} /* base64 encoded binary */{{/isByteArray}}{{/isQueryParam}}

samples/client/petstore/spring-http-interface-noResponseEntity/src/main/java/org/openapitools/api/FakeApi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ void testEndpointParameters(
216216
@RequestParam(value = "number", required = true) BigDecimal number,
217217
@RequestParam(value = "double", required = true) Double _double,
218218
@RequestParam(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,
219-
@RequestParam(value = "byte", required = true) byte[] _byte,
219+
@RequestParam(value = "byte", required = true) String _byte /* base64 encoded binary */,
220220
@RequestParam(value = "integer", required = false) Integer integer,
221221
@RequestParam(value = "int32", required = false) Integer int32,
222222
@RequestParam(value = "int64", required = false) Long int64,

samples/client/petstore/spring-http-interface-reactive-noResponseEntity/src/main/java/org/openapitools/api/FakeApi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ Mono<Void> testEndpointParameters(
220220
@RequestPart(value = "number", required = true) BigDecimal number,
221221
@RequestPart(value = "double", required = true) Double _double,
222222
@RequestPart(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,
223-
@RequestPart(value = "byte", required = true) byte[] _byte,
223+
@RequestPart(value = "byte", required = true) String _byte /* base64 encoded binary */,
224224
@RequestPart(value = "integer", required = false) Integer integer,
225225
@RequestPart(value = "int32", required = false) Integer int32,
226226
@RequestPart(value = "int64", required = false) Long int64,

samples/client/petstore/spring-http-interface-reactive/src/main/java/org/openapitools/api/FakeApi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ Mono<ResponseEntity<Void>> testEndpointParameters(
211211
@RequestPart(value = "number", required = true) BigDecimal number,
212212
@RequestPart(value = "double", required = true) Double _double,
213213
@RequestPart(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,
214-
@RequestPart(value = "byte", required = true) byte[] _byte,
214+
@RequestPart(value = "byte", required = true) String _byte /* base64 encoded binary */,
215215
@RequestPart(value = "integer", required = false) Integer integer,
216216
@RequestPart(value = "int32", required = false) Integer int32,
217217
@RequestPart(value = "int64", required = false) Long int64,

0 commit comments

Comments
 (0)