From c14c838a5ffbe4027d7edc426b73c64342958b38 Mon Sep 17 00:00:00 2001 From: iProdigy <8106344+iProdigy@users.noreply.github.com> Date: Sat, 30 Sep 2023 02:05:33 -0700 Subject: [PATCH] Optimize moshi decoding (#2183) * perf: avoid writing full body to an intermediate string * fix: eagerly return null for empty bodies * chore(moshi): remove guava dependency --------- Co-authored-by: Marvin Froeder --- moshi/pom.xml | 6 ----- .../main/java/feign/moshi/MoshiDecoder.java | 24 ++++++------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/moshi/pom.xml b/moshi/pom.xml index a97784d2c..e674a1237 100644 --- a/moshi/pom.xml +++ b/moshi/pom.xml @@ -42,12 +42,6 @@ moshi - - com.google.guava - guava - ${guava.version} - - ${project.groupId} feign-core diff --git a/moshi/src/main/java/feign/moshi/MoshiDecoder.java b/moshi/src/main/java/feign/moshi/MoshiDecoder.java index 82b2f8503..23c7fe855 100644 --- a/moshi/src/main/java/feign/moshi/MoshiDecoder.java +++ b/moshi/src/main/java/feign/moshi/MoshiDecoder.java @@ -13,19 +13,16 @@ */ package feign.moshi; -import com.google.common.io.CharStreams; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonEncodingException; import com.squareup.moshi.Moshi; import feign.Response; import feign.Util; import feign.codec.Decoder; +import okio.BufferedSource; +import okio.Okio; import java.io.IOException; -import java.io.Reader; import java.lang.reflect.Type; -import static feign.Util.UTF_8; -import static feign.Util.ensureClosed; public class MoshiDecoder implements Decoder { private final Moshi moshi; @@ -42,7 +39,6 @@ public MoshiDecoder(Iterable> adapters) { this(MoshiFactory.create(adapters)); } - @Override public Object decode(Response response, Type type) throws IOException { JsonAdapter jsonAdapter = moshi.adapter(type); @@ -52,23 +48,17 @@ public Object decode(Response response, Type type) throws IOException { if (response.body() == null) return null; - Reader reader = response.body().asReader(UTF_8); - - try { - return parseJson(jsonAdapter, reader); + try (BufferedSource source = Okio.buffer(Okio.source(response.body().asInputStream()))) { + if (source.exhausted()) { + return null; // empty body + } + return jsonAdapter.fromJson(source); } catch (JsonDataException e) { if (e.getCause() != null && e.getCause() instanceof IOException) { throw (IOException) e.getCause(); } throw e; - } finally { - ensureClosed(reader); } } - private Object parseJson(JsonAdapter jsonAdapter, Reader reader) throws IOException { - String targetString = CharStreams.toString(reader); - return jsonAdapter.fromJson(targetString); - } } -