Skip to content

Commit b844d8d

Browse files
authored
[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
1 parent 338f7f2 commit b844d8d

File tree

34 files changed

+701
-307
lines changed

34 files changed

+701
-307
lines changed

bin/utils/test_file_list.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/ClientTest.java"
1111
sha256: 325fdd5d7e2c97790c0fb44f712ab7b2ba022d7e1a5b0056f47b07f342682b6d
1212
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java"
13-
sha256: e673d9928c8eb848262d0116fe0d28db832e128671a810a7c966d06d90cb9b63
13+
sha256: 67941355a0a27ed9ff9318b1caa103e78b81b9aff61b594b18be5cd2bb9f6591
1414
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/api/PetApiTest.java"
1515
sha256: 8b1b8f2a2ad00ccb090873a94a5f73e328b98317d2ec715f53bd7a1accb2a023
1616
- filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java"

modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,17 +1166,8 @@ public class ApiClient {
11661166
return (T) downloadFileFromResponse(response);
11671167
}
11681168
1169-
String respBody;
1170-
try {
1171-
if (response.body() != null)
1172-
respBody = response.body().string();
1173-
else
1174-
respBody = null;
1175-
} catch (IOException e) {
1176-
throw new ApiException(e);
1177-
}
1178-
1179-
if (respBody == null || "".equals(respBody)) {
1169+
ResponseBody respBody = response.body();
1170+
if (respBody == null) {
11801171
return null;
11811172
}
11821173
@@ -1185,17 +1176,25 @@ public class ApiClient {
11851176
// ensuring a default content type
11861177
contentType = "application/json";
11871178
}
1188-
if (isJsonMime(contentType)) {
1189-
return JSON.deserialize(respBody, returnType);
1190-
} else if (returnType.equals(String.class)) {
1191-
// Expecting string, return the raw response body.
1192-
return (T) respBody;
1193-
} else {
1194-
throw new ApiException(
1179+
try {
1180+
if (isJsonMime(contentType)) {
1181+
return JSON.deserialize(respBody.byteStream(), returnType);
1182+
} else if (returnType.equals(String.class)) {
1183+
String respBodyString = respBody.string();
1184+
if (respBodyString.isEmpty()) {
1185+
return null;
1186+
}
1187+
// Expecting string, return the raw response body.
1188+
return (T) respBodyString;
1189+
} else {
1190+
throw new ApiException(
11951191
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
11961192
response.code(),
11971193
response.headers().toMultimap(),
1198-
respBody);
1194+
response.body().string());
1195+
}
1196+
} catch (IOException e) {
1197+
throw new ApiException(e);
11991198
}
12001199
}
12011200

modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/JSON.mustache

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ import org.joda.time.format.ISODateTimeFormat;
2323
import okio.ByteString;
2424

2525
import java.io.IOException;
26+
import java.io.InputStream;
27+
import java.io.InputStreamReader;
2628
import java.io.StringReader;
2729
import java.lang.reflect.Type;
30+
import java.nio.charset.StandardCharsets;
2831
import java.text.DateFormat;
2932
import java.text.ParseException;
3033
import java.text.ParsePosition;
@@ -198,6 +201,28 @@ public class JSON {
198201
}
199202
}
200203

204+
/**
205+
* Deserialize the given JSON InputStream to a Java object.
206+
*
207+
* @param <T> Type
208+
* @param inputStream The JSON InputStream
209+
* @param returnType The type to deserialize into
210+
* @return The deserialized Java object
211+
*/
212+
@SuppressWarnings("unchecked")
213+
public static <T> T deserialize(InputStream inputStream, Type returnType) throws IOException {
214+
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
215+
if (isLenientOnJson) {
216+
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
217+
JsonReader jsonReader = new JsonReader(reader);
218+
jsonReader.setLenient(true);
219+
return gson.fromJson(jsonReader, returnType);
220+
} else {
221+
return gson.fromJson(reader, returnType);
222+
}
223+
}
224+
}
225+
201226
/**
202227
* Gson TypeAdapter for Byte Array type
203228
*/

samples/client/echo_api/java/okhttp-gson-user-defined-templates/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,17 +1006,8 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
10061006
return (T) downloadFileFromResponse(response);
10071007
}
10081008

1009-
String respBody;
1010-
try {
1011-
if (response.body() != null)
1012-
respBody = response.body().string();
1013-
else
1014-
respBody = null;
1015-
} catch (IOException e) {
1016-
throw new ApiException(e);
1017-
}
1018-
1019-
if (respBody == null || "".equals(respBody)) {
1009+
ResponseBody respBody = response.body();
1010+
if (respBody == null) {
10201011
return null;
10211012
}
10221013

@@ -1025,17 +1016,25 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
10251016
// ensuring a default content type
10261017
contentType = "application/json";
10271018
}
1028-
if (isJsonMime(contentType)) {
1029-
return JSON.deserialize(respBody, returnType);
1030-
} else if (returnType.equals(String.class)) {
1031-
// Expecting string, return the raw response body.
1032-
return (T) respBody;
1033-
} else {
1034-
throw new ApiException(
1019+
try {
1020+
if (isJsonMime(contentType)) {
1021+
return JSON.deserialize(respBody.byteStream(), returnType);
1022+
} else if (returnType.equals(String.class)) {
1023+
String respBodyString = respBody.string();
1024+
if (respBodyString.isEmpty()) {
1025+
return null;
1026+
}
1027+
// Expecting string, return the raw response body.
1028+
return (T) respBodyString;
1029+
} else {
1030+
throw new ApiException(
10351031
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
10361032
response.code(),
10371033
response.headers().toMultimap(),
1038-
respBody);
1034+
response.body().string());
1035+
}
1036+
} catch (IOException e) {
1037+
throw new ApiException(e);
10391038
}
10401039
}
10411040

samples/client/echo_api/java/okhttp-gson-user-defined-templates/src/main/java/org/openapitools/client/JSON.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
import okio.ByteString;
2828

2929
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.io.InputStreamReader;
3032
import java.io.StringReader;
3133
import java.lang.reflect.Type;
34+
import java.nio.charset.StandardCharsets;
3235
import java.text.DateFormat;
3336
import java.text.ParseException;
3437
import java.text.ParsePosition;
@@ -164,6 +167,28 @@ public static <T> T deserialize(String body, Type returnType) {
164167
}
165168
}
166169

170+
/**
171+
* Deserialize the given JSON InputStream to a Java object.
172+
*
173+
* @param <T> Type
174+
* @param inputStream The JSON InputStream
175+
* @param returnType The type to deserialize into
176+
* @return The deserialized Java object
177+
*/
178+
@SuppressWarnings("unchecked")
179+
public static <T> T deserialize(InputStream inputStream, Type returnType) throws IOException {
180+
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
181+
if (isLenientOnJson) {
182+
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
183+
JsonReader jsonReader = new JsonReader(reader);
184+
jsonReader.setLenient(true);
185+
return gson.fromJson(jsonReader, returnType);
186+
} else {
187+
return gson.fromJson(reader, returnType);
188+
}
189+
}
190+
}
191+
167192
/**
168193
* Gson TypeAdapter for Byte Array type
169194
*/

samples/client/echo_api/java/okhttp-gson/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -936,17 +936,8 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
936936
return (T) downloadFileFromResponse(response);
937937
}
938938

939-
String respBody;
940-
try {
941-
if (response.body() != null)
942-
respBody = response.body().string();
943-
else
944-
respBody = null;
945-
} catch (IOException e) {
946-
throw new ApiException(e);
947-
}
948-
949-
if (respBody == null || "".equals(respBody)) {
939+
ResponseBody respBody = response.body();
940+
if (respBody == null) {
950941
return null;
951942
}
952943

@@ -955,17 +946,25 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
955946
// ensuring a default content type
956947
contentType = "application/json";
957948
}
958-
if (isJsonMime(contentType)) {
959-
return JSON.deserialize(respBody, returnType);
960-
} else if (returnType.equals(String.class)) {
961-
// Expecting string, return the raw response body.
962-
return (T) respBody;
963-
} else {
964-
throw new ApiException(
949+
try {
950+
if (isJsonMime(contentType)) {
951+
return JSON.deserialize(respBody.byteStream(), returnType);
952+
} else if (returnType.equals(String.class)) {
953+
String respBodyString = respBody.string();
954+
if (respBodyString.isEmpty()) {
955+
return null;
956+
}
957+
// Expecting string, return the raw response body.
958+
return (T) respBodyString;
959+
} else {
960+
throw new ApiException(
965961
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
966962
response.code(),
967963
response.headers().toMultimap(),
968-
respBody);
964+
response.body().string());
965+
}
966+
} catch (IOException e) {
967+
throw new ApiException(e);
969968
}
970969
}
971970

samples/client/echo_api/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
import okio.ByteString;
2828

2929
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.io.InputStreamReader;
3032
import java.io.StringReader;
3133
import java.lang.reflect.Type;
34+
import java.nio.charset.StandardCharsets;
3235
import java.text.DateFormat;
3336
import java.text.ParseException;
3437
import java.text.ParsePosition;
@@ -168,6 +171,28 @@ public static <T> T deserialize(String body, Type returnType) {
168171
}
169172
}
170173

174+
/**
175+
* Deserialize the given JSON InputStream to a Java object.
176+
*
177+
* @param <T> Type
178+
* @param inputStream The JSON InputStream
179+
* @param returnType The type to deserialize into
180+
* @return The deserialized Java object
181+
*/
182+
@SuppressWarnings("unchecked")
183+
public static <T> T deserialize(InputStream inputStream, Type returnType) throws IOException {
184+
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
185+
if (isLenientOnJson) {
186+
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
187+
JsonReader jsonReader = new JsonReader(reader);
188+
jsonReader.setLenient(true);
189+
return gson.fromJson(jsonReader, returnType);
190+
} else {
191+
return gson.fromJson(reader, returnType);
192+
}
193+
}
194+
}
195+
171196
/**
172197
* Gson TypeAdapter for Byte Array type
173198
*/

samples/client/others/java/okhttp-gson-oneOf-array/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -910,17 +910,8 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
910910
return (T) downloadFileFromResponse(response);
911911
}
912912

913-
String respBody;
914-
try {
915-
if (response.body() != null)
916-
respBody = response.body().string();
917-
else
918-
respBody = null;
919-
} catch (IOException e) {
920-
throw new ApiException(e);
921-
}
922-
923-
if (respBody == null || "".equals(respBody)) {
913+
ResponseBody respBody = response.body();
914+
if (respBody == null) {
924915
return null;
925916
}
926917

@@ -929,17 +920,25 @@ public <T> T deserialize(Response response, Type returnType) throws ApiException
929920
// ensuring a default content type
930921
contentType = "application/json";
931922
}
932-
if (isJsonMime(contentType)) {
933-
return JSON.deserialize(respBody, returnType);
934-
} else if (returnType.equals(String.class)) {
935-
// Expecting string, return the raw response body.
936-
return (T) respBody;
937-
} else {
938-
throw new ApiException(
923+
try {
924+
if (isJsonMime(contentType)) {
925+
return JSON.deserialize(respBody.byteStream(), returnType);
926+
} else if (returnType.equals(String.class)) {
927+
String respBodyString = respBody.string();
928+
if (respBodyString.isEmpty()) {
929+
return null;
930+
}
931+
// Expecting string, return the raw response body.
932+
return (T) respBodyString;
933+
} else {
934+
throw new ApiException(
939935
"Content type \"" + contentType + "\" is not supported for type: " + returnType,
940936
response.code(),
941937
response.headers().toMultimap(),
942-
respBody);
938+
response.body().string());
939+
}
940+
} catch (IOException e) {
941+
throw new ApiException(e);
943942
}
944943
}
945944

samples/client/others/java/okhttp-gson-oneOf-array/src/main/java/org/openapitools/client/JSON.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
import okio.ByteString;
2828

2929
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.io.InputStreamReader;
3032
import java.io.StringReader;
3133
import java.lang.reflect.Type;
34+
import java.nio.charset.StandardCharsets;
3235
import java.text.DateFormat;
3336
import java.text.ParseException;
3437
import java.text.ParsePosition;
@@ -160,6 +163,28 @@ public static <T> T deserialize(String body, Type returnType) {
160163
}
161164
}
162165

166+
/**
167+
* Deserialize the given JSON InputStream to a Java object.
168+
*
169+
* @param <T> Type
170+
* @param inputStream The JSON InputStream
171+
* @param returnType The type to deserialize into
172+
* @return The deserialized Java object
173+
*/
174+
@SuppressWarnings("unchecked")
175+
public static <T> T deserialize(InputStream inputStream, Type returnType) throws IOException {
176+
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
177+
if (isLenientOnJson) {
178+
// see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
179+
JsonReader jsonReader = new JsonReader(reader);
180+
jsonReader.setLenient(true);
181+
return gson.fromJson(jsonReader, returnType);
182+
} else {
183+
return gson.fromJson(reader, returnType);
184+
}
185+
}
186+
}
187+
163188
/**
164189
* Gson TypeAdapter for Byte Array type
165190
*/

0 commit comments

Comments
 (0)