Browse Source

Merge pull request #64 from davidmc24/fix-default-decoder

Fix default decoder's support for Response decoding, clean up usage of S...
pull/65/merge
Adrian Cole 12 years ago
parent
commit
9067537cc2
  1. 7
      core/src/main/java/feign/FeignException.java
  2. 22
      core/src/main/java/feign/Util.java
  3. 13
      core/src/main/java/feign/codec/Decoder.java
  4. 21
      core/src/main/java/feign/codec/StringDecoder.java
  5. 13
      core/src/test/java/feign/codec/DefaultDecoderTest.java

7
core/src/main/java/feign/FeignException.java

@ -19,8 +19,6 @@ import static java.lang.String.format; @@ -19,8 +19,6 @@ import static java.lang.String.format;
import java.io.IOException;
import feign.codec.StringDecoder;
/**
* Origin exception type for all Http Apis.
*/
@ -29,14 +27,11 @@ public class FeignException extends RuntimeException { @@ -29,14 +27,11 @@ public class FeignException extends RuntimeException {
return new FeignException(format("%s %s %s", cause.getMessage(), request.method(), request.url(), 0), cause);
}
private static final StringDecoder toString = new StringDecoder();
public static FeignException errorStatus(String methodKey, Response response) {
String message = format("status %s reading %s", response.status(), methodKey);
try {
if (response.body() != null) {
String body = toString.decode(response, String.class).toString();
response = Response.create(response.status(), response.reason(), response.headers(), body);
String body = Util.toString(response.body().asReader());
message += "; content:\n" + body;
}
} catch (IOException ignored) { // NOPMD

22
core/src/main/java/feign/Util.java

@ -17,10 +17,12 @@ package feign; @@ -17,10 +17,12 @@ package feign;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
@ -163,4 +165,24 @@ public class Util { @@ -163,4 +165,24 @@ public class Util {
}
return types[types.length - 1];
}
private static final int BUF_SIZE = 0x800; // 2K chars (4K bytes)
public static String toString(Reader reader) throws IOException {
if (reader == null) {
return null;
}
try {
StringBuilder to = new StringBuilder();
CharBuffer buf = CharBuffer.allocate(BUF_SIZE);
while (reader.read(buf) != -1) {
buf.flip();
to.append(buf);
buf.clear();
}
return to.toString();
} finally {
ensureClosed(reader);
}
}
}

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

@ -17,6 +17,7 @@ package feign.codec; @@ -17,6 +17,7 @@ package feign.codec;
import feign.FeignException;
import feign.Response;
import feign.Util;
import java.io.IOException;
import java.lang.reflect.Type;
@ -74,16 +75,18 @@ public interface Decoder { @@ -74,16 +75,18 @@ public interface Decoder {
* signatures.
*/
public class Default implements Decoder {
private final StringDecoder stringDecoder = new StringDecoder();
@Override
public Object decode(Response response, Type type) throws IOException {
if (Response.class.equals(type)) {
return response;
} else if (String.class.equals(type)) {
return stringDecoder.decode(response, type);
String bodyString = null;
if (response.body() != null) {
bodyString = Util.toString(response.body().asReader());
}
return Response.create(response.status(), response.reason(), response.headers(), bodyString);
} else if (void.class.equals(type) || response.body() == null) {
return null;
} else if (String.class.equals(type)) {
return Util.toString(response.body().asReader());
}
throw new DecodeException(format("%s is not a type supported by this decoder.", type));
}

21
core/src/main/java/feign/codec/StringDecoder.java

@ -16,38 +16,21 @@ @@ -16,38 +16,21 @@
package feign.codec;
import feign.Response;
import feign.Util;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.nio.CharBuffer;
import static feign.Util.ensureClosed;
/**
* Adapted from {@code com.google.common.io.CharStreams.toString()}.
*/
public class StringDecoder implements Decoder {
private static final int BUF_SIZE = 0x800; // 2K chars (4K bytes)
@Override
public Object decode(Response response, Type type) throws IOException {
Response.Body body = response.body();
if (body == null) {
return null;
}
Reader from = body.asReader();
try {
StringBuilder to = new StringBuilder();
CharBuffer buf = CharBuffer.allocate(BUF_SIZE);
while (from.read(buf) != -1) {
buf.flip();
to.append(buf);
buf.clear();
}
return to.toString();
} finally {
ensureClosed(from);
}
return Util.toString(body.asReader());
}
}

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

@ -15,11 +15,12 @@ @@ -15,11 +15,12 @@
*/
package feign.codec;
import feign.FeignException;
import feign.Response;
import feign.Util;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import java.io.StringReader;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@ -38,19 +39,19 @@ public class DefaultDecoderTest { @@ -38,19 +39,19 @@ public class DefaultDecoderTest {
@Test public void testDecodesToResponse() throws Exception {
Response response = knownResponse();
Object decodedObject = decoder.decode(response, Response.class);
assertEquals(decodedObject.getClass(), Response.class, "");
assertEquals(decodedObject.getClass(), Response.class);
Response decodedResponse = (Response) decodedObject;
assertEquals(decodedResponse.status(), response.status());
assertEquals(decodedResponse.reason(), response.reason());
assertEquals(decodedResponse.headers(), response.headers());
assertEquals(decodedResponse.body().toString(), response.body().toString());
assertEquals(Util.toString(decodedResponse.body().asReader()), "response body");
}
@Test public void testDecodesToString() throws Exception {
Response response = knownResponse();
Object decodedObject = decoder.decode(response, String.class);
assertEquals(decodedObject.getClass(), String.class);
assertEquals(decodedObject.toString(), response.body().toString());
assertEquals(decodedObject.toString(), "response body");
}
@Test public void testDecodesNullBodyToNull() throws Exception {
@ -63,9 +64,11 @@ public class DefaultDecoderTest { @@ -63,9 +64,11 @@ public class DefaultDecoderTest {
}
private Response knownResponse() {
String content = "response body";
StringReader reader = new StringReader(content);
Map<String, Collection<String>> headers = new HashMap<String, Collection<String>>();
headers.put("Content-Type", Collections.singleton("text/plain"));
return Response.create(200, "OK", headers, "response body");
return Response.create(200, "OK", headers, reader, content.length());
}
private Response nullBodyResponse() {

Loading…
Cancel
Save