swagger-api / swagger-api/swagger-codegen
[JAVA] Gson exception when deserializing type=string format=byte to byte[]
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
When processing a JSON response body containing a field with base64-encoded data (type=string, format=byte), the Gson deserializer throws an the following exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 13 path $.content] with root cause
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 13 path $.content
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:351)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
at com.google.gson.Gson.fromJson(Gson.java:932)
at com.google.gson.Gson.fromJson(Gson.java:897)
at com.google.gson.Gson.fromJson(Gson.java:846)
at nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.JSON.deserialize(JSON.java:134)
at nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.ApiClient.deserialize(ApiClient.java:710)
at nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.ApiClient.handleResponse(ApiClient.java:913)
at nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.ApiClient.execute(ApiClient.java:840)
...
Swagger-codegen version
3.0.23
Swagger declaration file content or url
The following schema (part of the declaration file) corresponds to the object that cannot be deserialized. More, specifically, content is the offending field here:
{
"BinaryContentDTO": {
"required" : [
"content",
"mediaType",
"suggestedFileName"
],
"type" : "object",
"properties": {
"content" : {
"type" : "string",
"format": "byte"
},
"suggestedFileName": {
"type": "string"
},
"mediaType" : {
"type": "string"
}
}
}
}
Command line used for generation
<plugin>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.23</version>
<executions>
<execution>
<id>swagger-ats-java</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>../swagger-docs/ats-api-docs.json</inputSpec>
<language>java</language>
<invokerPackage>nl.pompkracht.portal.port.adapter.out.rest.ats.swagger</invokerPackage>
<apiPackage>nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.api</apiPackage>
<modelPackage>nl.pompkracht.portal.port.adapter.out.rest.ats.swagger.model</modelPackage>
<output>target/generated-sources/swagger-ats</output>
<ignoreFileOverride>/dev/null</ignoreFileOverride>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<configOptions>
<dateLibrary>java8</dateLibrary>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
Steps to reproduce
- Generate Java client from OpenAPI spec with an operation that contains base-64 encoded data in the response body
- Call the relevant method in the generated code
- Verify that the Gson exception occurs
Related issues/PRs
Found an issue with serializing byte[] array types from generated server code, but this applies to consuming base64 data from generated client code, so not really related I think
Suggest a fix/enhancement
Was able to work around the issue by adding a JsonDeserializer type adapter for byte arrays to gson, like this:
ApiClient apiClient = new ApiClient();
var serializer = apiClient.getJSON();
serializer.setGson(serializer.getGson().newBuilder()
.registerTypeAdapter(byte[].class, new ByteArrayDeserializer())
.create()
);
....
private static class ByteArrayDeserializer implements JsonDeserializer<byte[]> {
@Override
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Base64.getDecoder().decode(json.getAsString());
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the response deserialization path through JSON.deserialize and ApiClient.deserialize, then inspect how Gson's ArrayTypeAdapter handles the byte[] field. Done means a generated Java client can deserialize a type=string, format=byte response without the reported exception, while preserving normal byte-array handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100