Skip to content

Commit aa4bb91

Browse files
committed
ApiClient: support deserializing JSON from InputStream instead of String to bypass 2GB Java String limit
1 parent 4c08ff8 commit aa4bb91

File tree

35 files changed

+705
-311
lines changed

35 files changed

+705
-311
lines changed

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
*/

modules/openapi-generator/src/main/resources/elixir/connection.ex.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ defmodule {{moduleName}}.Connection do
9696
of the function call, will be set as a bearer token in the
9797
`authorization` header.
9898
{{/hasOAuthMethods}}
99-
- `options`: a keyword list of OpenAPIPetstore.Connection.options.
99+
- `options`: a keyword list of {{moduleName}}.Connection.options.
100100

101101
### Returns
102102

@@ -133,7 +133,7 @@ defmodule {{moduleName}}.Connection do
133133
that returns a bearer token.
134134
- `scopes_or_password`: a list of Strings represenging OAuth2 scopes, or
135135
a single string that is the password for the username provided.
136-
- `options`: a keyword list of OpenAPIPetstore.Connection.options.
136+
- `options`: a keyword list of {{moduleName}}.Connection.options.
137137

138138
### Returns
139139

@@ -155,7 +155,7 @@ defmodule {{moduleName}}.Connection do
155155
of the function call, will be set as a bearer token in the
156156
`authorization` header.
157157
- `scopes`: a list of Strings represenging OAuth2 scopes.
158-
- `options`: a keyword list of OpenAPIPetstore.Connection.options.
158+
- `options`: a keyword list of {{moduleName}}.Connection.options.
159159

160160
### Returns
161161

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

0 commit comments

Comments
 (0)