Skip to content

Commit 2bb7968

Browse files
author
adriancole
committed
Decoder.decode() is no longer called for Response or void types.
1 parent d105286 commit 2bb7968

File tree

9 files changed

+43
-51
lines changed

9 files changed

+43
-51
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
### Version 5.0.1
2+
* `Decoder.decode()` is no longer called for `Response` or `void` types.
3+
14
### Version 5.0
25
* Remove support for Observable methods.
36
* Use single non-generic Decoder/Encoder instead of sets of type-specific Decoders/Encoders.

core/src/main/java/feign/MethodHandler.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,17 @@ Object executeAndDecode(RequestTemplate template) throws Throwable {
143143
response = logger.logAndRebufferResponse(metadata.configKey(), logLevel.get(), response, elapsedTime);
144144
}
145145
if (response.status() >= 200 && response.status() < 300) {
146-
return decode(response);
146+
if (Response.class == metadata.returnType()) {
147+
if (response.body() == null) {
148+
return response;
149+
}
150+
String bodyString = Util.toString(response.body().asReader());
151+
return Response.create(response.status(), response.reason(), response.headers(), bodyString);
152+
} else if (void.class == metadata.returnType()) {
153+
return null;
154+
} else {
155+
return decode(response);
156+
}
147157
} else {
148158
throw errorDecoder.decode(metadata.configKey(), response);
149159
}

core/src/main/java/feign/codec/Decoder.java

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,14 @@
2626

2727
/**
2828
* Decodes an HTTP response into a single object of the given {@code Type}. Invoked when
29-
* {@link Response#status()} is in the 2xx range. Like
30-
* {@code javax.websocket.Decoder}, except that the decode method is passed the
31-
* generic type of the target.
32-
*
33-
* <p>
29+
* {@link Response#status()} is in the 2xx range and the return type is neither {@code void} nor {@code Response}.
30+
* <p/>
31+
* <p/>
3432
* Example Implementation:<br>
3533
* <p/>
3634
* <pre>
3735
* public class GsonDecoder implements Decoder {
38-
* private final Gson gson;
39-
*
40-
* public GsonDecoder(Gson gson) {
41-
* this.gson = gson;
42-
* }
36+
* private final Gson gson = new Gson();
4337
*
4438
* &#064;Override
4539
* public Object decode(Response response, Type type) throws IOException {
@@ -62,7 +56,7 @@ public interface Decoder {
6256
* If you need to wrap exceptions, please do so via {@link DecodeException}.
6357
*
6458
* @param response the response to decode
65-
* @param type Target object type.
59+
* @param type Target object type.
6660
* @return instance of {@code type}
6761
* @throws IOException will be propagated safely to the caller.
6862
* @throws DecodeException when decoding failed due to a checked exception besides IOException.
@@ -71,19 +65,12 @@ public interface Decoder {
7165
Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;
7266

7367
/**
74-
* Default implementation of {@code Decoder} that supports {@code void}, {@code Response}, and {@code String}
75-
* signatures.
68+
* Default implementation of {@code Decoder} that supports {@code String} signatures.
7669
*/
7770
public class Default implements Decoder {
7871
@Override
7972
public Object decode(Response response, Type type) throws IOException {
80-
if (Response.class.equals(type)) {
81-
String bodyString = null;
82-
if (response.body() != null) {
83-
bodyString = Util.toString(response.body().asReader());
84-
}
85-
return Response.create(response.status(), response.reason(), response.headers(), bodyString);
86-
} else if (void.class.equals(type) || response.body() == null) {
73+
if (response.body() == null) {
8774
return null;
8875
} else if (String.class.equals(type)) {
8976
return Util.toString(response.body().asReader());

core/src/test/java/feign/FeignTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
public class FeignTest {
5656

5757
interface TestInterface {
58+
@RequestLine("POST /") Response response();
59+
5860
@RequestLine("POST /") String post();
5961

6062
@RequestLine("POST /")
@@ -141,6 +143,24 @@ public void postTemplateParamsResolve() throws IOException, InterruptedException
141143
}
142144
}
143145

146+
@Test
147+
public void responseCoercesToStringBody() throws IOException, InterruptedException {
148+
final MockWebServer server = new MockWebServer();
149+
server.enqueue(new MockResponse().setBody("foo"));
150+
server.play();
151+
152+
try {
153+
TestInterface api = Feign.create(TestInterface.class, "http://localhost:" + server.getPort(),
154+
new TestInterface.Module());
155+
156+
Response response = api.response();
157+
assertTrue(response.body().isRepeatable());
158+
assertEquals(response.body().toString(), "foo");
159+
} finally {
160+
server.shutdown();
161+
}
162+
}
163+
144164
@Test
145165
public void postFormParams() throws IOException, InterruptedException {
146166
final MockWebServer server = new MockWebServer();

core/src/test/java/feign/codec/DefaultDecoderTest.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,6 @@
3232
public class DefaultDecoderTest {
3333
private final Decoder decoder = new Decoder.Default();
3434

35-
@Test public void testDecodesToVoid() throws Exception {
36-
assertEquals(decoder.decode(knownResponse(), void.class), null);
37-
}
38-
39-
@Test public void testDecodesToResponse() throws Exception {
40-
Response response = knownResponse();
41-
Object decodedObject = decoder.decode(response, Response.class);
42-
assertEquals(decodedObject.getClass(), Response.class);
43-
Response decodedResponse = (Response) decodedObject;
44-
assertEquals(decodedResponse.status(), response.status());
45-
assertEquals(decodedResponse.reason(), response.reason());
46-
assertEquals(decodedResponse.headers(), response.headers());
47-
assertEquals(Util.toString(decodedResponse.body().asReader()), "response body");
48-
}
49-
5035
@Test public void testDecodesToString() throws Exception {
5136
Response response = knownResponse();
5237
Object decodedObject = decoder.decode(response, String.class);

gson/src/main/java/feign/gson/GsonModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ static class GsonCodec implements Encoder, Decoder {
103103
}
104104

105105
@Override public Object decode(Response response, Type type) throws IOException {
106-
if (void.class.equals(type) || response.body() == null) {
106+
if (response.body() == null) {
107107
return null;
108108
}
109109
Reader reader = response.body().asReader();

gson/src/test/java/feign/gson/GsonModuleTest.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,6 @@ static class DecoderBindings {
133133
}.getType()), zones);
134134
}
135135

136-
@Test public void voidDecodesToNull() throws Exception {
137-
DecoderBindings bindings = new DecoderBindings();
138-
ObjectGraph.create(bindings).inject(bindings);
139-
140-
Response response = Response.create(200, "OK", Collections.<String, Collection<String>>emptyMap(), zonesJson);
141-
assertEquals(bindings.decoder.decode(response, void.class), null);
142-
}
143-
144136
@Test public void nullBodyDecodesToNull() throws Exception {
145137
DecoderBindings bindings = new DecoderBindings();
146138
ObjectGraph.create(bindings).inject(bindings);

sax/src/main/java/feign/sax/SAXDecoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ private SAXDecoder(Map<Type, Provider<? extends ContentHandlerWithResult<?>>> ha
143143

144144
@Override
145145
public Object decode(Response response, Type type) throws IOException, DecodeException {
146-
if (void.class.equals(type) || response.body() == null) {
146+
if (response.body() == null) {
147147
return null;
148148
}
149149
Provider<? extends ContentHandlerWithResult<?>> handlerProvider = handlerProviders.get(type);

sax/src/test/java/feign/sax/SAXDecoderTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,6 @@ public void characters(char ch[], int start, int length) {
136136
}
137137
}
138138

139-
@Test public void voidDecodesToNull() throws Exception {
140-
Response response = Response.create(200, "OK", Collections.<String, Collection<String>>emptyMap(), statusFailed);
141-
assertEquals(decoder.decode(response, void.class), null);
142-
}
143-
144139
@Test public void nullBodyDecodesToNull() throws Exception {
145140
Response response = Response.create(204, "OK", Collections.<String, Collection<String>>emptyMap(), null);
146141
assertEquals(decoder.decode(response, String.class), null);

0 commit comments

Comments
 (0)