[Java] ApiClient: support deserializing from InputStream instead of String to bypass 2GB Java String limit (#21115)

* ApiClient: support deserializing JSON from InputStream instead of String to bypass 2GB Java String limit

* Update test_file_list.yaml
This commit is contained in:
Kevin Lin
2025-04-22 23:59:02 -07:00
committed by GitHub
parent 338f7f2a09
commit b844d8d4cd
34 changed files with 701 additions and 307 deletions

View File

@@ -936,17 +936,8 @@ public class ApiClient {
return (T) downloadFileFromResponse(response);
}
String respBody;
try {
if (response.body() != null)
respBody = response.body().string();
else
respBody = null;
} catch (IOException e) {
throw new ApiException(e);
}
if (respBody == null || "".equals(respBody)) {
ResponseBody respBody = response.body();
if (respBody == null) {
return null;
}
@@ -955,17 +946,25 @@ public class ApiClient {
// ensuring a default content type
contentType = "application/json";
}
if (isJsonMime(contentType)) {
return JSON.deserialize(respBody, returnType);
} else if (returnType.equals(String.class)) {
// Expecting string, return the raw response body.
return (T) respBody;
} else {
throw new ApiException(
try {
if (isJsonMime(contentType)) {
return JSON.deserialize(respBody.byteStream(), returnType);
} else if (returnType.equals(String.class)) {
String respBodyString = respBody.string();
if (respBodyString.isEmpty()) {
return null;
}
// Expecting string, return the raw response body.
return (T) respBodyString;
} else {
throw new ApiException(
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
response.code(),
response.headers().toMultimap(),
respBody);
response.body().string());
}
} catch (IOException e) {
throw new ApiException(e);
}
}

View File

@@ -27,8 +27,11 @@ import io.gsonfire.TypeSelector;
import okio.ByteString;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
@@ -168,6 +171,28 @@ public class JSON {
}
}
/**
* Deserialize the given JSON InputStream to a Java object.
*
* @param <T> Type
* @param inputStream The JSON InputStream
* @param returnType The type to deserialize into
* @return The deserialized Java object
*/
@SuppressWarnings("unchecked")
public static <T> T deserialize(InputStream inputStream, Type returnType) throws IOException {
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
if (isLenientOnJson) {
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
JsonReader jsonReader = new JsonReader(reader);
jsonReader.setLenient(true);
return gson.fromJson(jsonReader, returnType);
} else {
return gson.fromJson(reader, returnType);
}
}
}
/**
* Gson TypeAdapter for Byte Array type
*/