From 4edc4f693612fc6534a043e69de8b01baac6b2c9 Mon Sep 17 00:00:00 2001 From: jongmin-chung Date: Fri, 15 Aug 2025 00:55:33 +0900 Subject: [PATCH 1/4] fix: Java Byte to OAS integer data type --- .../src/main/java/io/swagger/v3/core/util/PrimitiveType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java index 4ec3b94ecc..0b33bad3a6 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java @@ -63,7 +63,7 @@ public Schema createProperty() { } @Override public Schema createProperty31() { - return new JsonSchema().typesItem("string").format("byte"); + return new JsonSchema().typesItem("integer").format("int8"); } }, BINARY(Byte.class, "binary") { From 02b2228879fe5fb14abafd36e7f8a5325de365be Mon Sep 17 00:00:00 2001 From: jongmin-chung Date: Fri, 15 Aug 2025 02:11:16 +0900 Subject: [PATCH 2/4] test: add ByteObject schema generation test for OAS 3.1 --- .../resolving/v31/ByteObjectOAS31Test.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java new file mode 100644 index 0000000000..d81ff7f6ed --- /dev/null +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java @@ -0,0 +1,78 @@ +package io.swagger.v3.core.resolving.v31; + +import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.core.converter.ModelConverterContextImpl; +import io.swagger.v3.core.jackson.ModelResolver; +import io.swagger.v3.core.matchers.SerializationMatchers; +import io.swagger.v3.core.resolving.SwaggerTestBase; +import io.swagger.v3.oas.annotations.media.Schema; +import org.testng.annotations.Test; + +import java.util.Map; + +public class ByteObjectOAS31Test extends SwaggerTestBase { + + @Test(description = "Test ByteObject schema generation with OAS 3.1") + public void testByteObjectSchemaOAS31() { + final ModelResolver modelResolver = new ModelResolver(mapper()).openapi31(true); + ModelConverterContextImpl context = new ModelConverterContextImpl(modelResolver); + + io.swagger.v3.oas.models.media.Schema model = context.resolve(new AnnotatedType(ByteObject.class)); + + Map definedModels = context.getDefinedModels(); + + SerializationMatchers.assertEqualsToYaml31(definedModels, "ByteObject:\n" + + " type: object\n" + + " properties:\n" + + " primitiveWithoutSchema:\n" + + " type: integer\n" + + " format: int8\n" + + " writeOnly: true\n" + + " primitiveWithSchema:\n" + + " type: integer\n" + + " format: int8\n" + + " writeOnly: true\n" + + " primitiveWithSchemaTypeAndFormat:\n" + + " type: integer\n" + + " format: int8\n" + + " writeOnly: true"); + } + + public static class ByteObject { + + private byte primitiveWithoutSchema; + + @Schema + private byte primitiveWithSchema; + + @Schema( + type = "string", + format = "byte" + ) + private byte primitiveWithSchemaTypeAndFormat; + + public byte primitiveWithoutSchema() { + return primitiveWithoutSchema; + } + + public byte primitiveWithSchema() { + return primitiveWithSchema; + } + + public byte primitiveWithSchemaTypeAndFormat() { + return primitiveWithSchemaTypeAndFormat; + } + + public void setPrimitiveWithoutSchema(byte primitiveWithoutSchema) { + this.primitiveWithoutSchema = primitiveWithoutSchema; + } + + public void setPrimitiveWithSchema(byte primitiveWithSchema) { + this.primitiveWithSchema = primitiveWithSchema; + } + + public void setPrimitiveWithSchemaTypeAndFormat(byte primitiveWithSchemaTypeAndFormat) { + this.primitiveWithSchemaTypeAndFormat = primitiveWithSchemaTypeAndFormat; + } + } +} From 7e4544a4cf8b8c4a757e12560aaed4d2a23f1bb6 Mon Sep 17 00:00:00 2001 From: jongmin-chung Date: Thu, 21 Aug 2025 00:59:25 +0900 Subject: [PATCH 3/4] fix: remove format format("int8") --- .../src/main/java/io/swagger/v3/core/util/PrimitiveType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java index 0b33bad3a6..d5ef60e090 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java @@ -63,7 +63,7 @@ public Schema createProperty() { } @Override public Schema createProperty31() { - return new JsonSchema().typesItem("integer").format("int8"); + return new JsonSchema().typesItem("integer"); } }, BINARY(Byte.class, "binary") { From eab93d7eb5f5c9b5d70dd956fa38550ac6b68bd2 Mon Sep 17 00:00:00 2001 From: jongmin-chung Date: Thu, 21 Aug 2025 00:59:48 +0900 Subject: [PATCH 4/4] feat: byte[] handling --- .../v3/core/jackson/ModelResolver.java | 7 +++ .../resolving/v31/ByteObjectOAS31Test.java | 43 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java index 8288007a42..7459721271 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java @@ -173,6 +173,13 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context type = _mapper.constructType(annotatedType.getType()); } + // EARLY special handling for OpenAPI 3.1 and byte[]: treat as array of primitive items + if (openapi31 && type.getRawClass().isArray() && type.getRawClass().getComponentType() == byte.class) { + ArraySchema arraySchema = new ArraySchema().items(PrimitiveType.BYTE.createProperty31()); + arraySchema.specVersion(SpecVersion.V31); + return arraySchema; + } + final Annotation resolvedSchemaOrArrayAnnotation = AnnotationsUtils.mergeSchemaAnnotations(annotatedType.getCtxAnnotations(), type); final io.swagger.v3.oas.annotations.media.Schema resolvedSchemaAnnotation = resolvedSchemaOrArrayAnnotation == null ? diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java index d81ff7f6ed..56f5b0e670 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/v31/ByteObjectOAS31Test.java @@ -5,6 +5,7 @@ import io.swagger.v3.core.jackson.ModelResolver; import io.swagger.v3.core.matchers.SerializationMatchers; import io.swagger.v3.core.resolving.SwaggerTestBase; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; import org.testng.annotations.Test; @@ -26,16 +27,24 @@ public void testByteObjectSchemaOAS31() { " properties:\n" + " primitiveWithoutSchema:\n" + " type: integer\n" + - " format: int8\n" + " writeOnly: true\n" + " primitiveWithSchema:\n" + " type: integer\n" + - " format: int8\n" + " writeOnly: true\n" + " primitiveWithSchemaTypeAndFormat:\n" + " type: integer\n" + - " format: int8\n" + - " writeOnly: true"); + " writeOnly: true\n" + + " primitiveArrayWithoutSchema:\n" + + " type: array\n" + + " items:\n" + + " type: integer\n" + + " writeOnly: true\n" + + " primitiveArrayWithSchema:\n" + + " type: array\n" + + " items:\n" + + " type: integer\n" + + " writeOnly: true" + ); } public static class ByteObject { @@ -51,6 +60,16 @@ public static class ByteObject { ) private byte primitiveWithSchemaTypeAndFormat; + private byte[] primitiveArrayWithoutSchema; + + @ArraySchema( + schema = @Schema( + type = "string", + format = "byte" + ) + ) + private byte[] primitiveArrayWithSchema; + public byte primitiveWithoutSchema() { return primitiveWithoutSchema; } @@ -74,5 +93,21 @@ public void setPrimitiveWithSchema(byte primitiveWithSchema) { public void setPrimitiveWithSchemaTypeAndFormat(byte primitiveWithSchemaTypeAndFormat) { this.primitiveWithSchemaTypeAndFormat = primitiveWithSchemaTypeAndFormat; } + + public byte[] primitiveArrayWithoutSchema() { + return primitiveArrayWithoutSchema; + } + + public void setPrimitiveArrayWithoutSchema(byte[] primitiveArrayWithoutSchema) { + this.primitiveArrayWithoutSchema = primitiveArrayWithoutSchema; + } + + public byte[] primitiveArrayWithSchema() { + return primitiveArrayWithSchema; + } + + public void setPrimitiveArrayWithSchema(byte[] primitiveArrayWithSchema) { + this.primitiveArrayWithSchema = primitiveArrayWithSchema; + } } }