Commit 8756a888 by Spencer Gibb

allow feign to decode parameterized types. Added SpringDecoderTests.

fixes gh-57
parent bebcf660
......@@ -2,6 +2,7 @@ package org.springframework.cloud.netflix.feign;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -31,18 +32,17 @@ public class SpringDecoder implements Decoder {
@Override
public Object decode(final Response response, Type type) throws IOException, FeignException {
if (type instanceof Class) {
@SuppressWarnings({ "unchecked", "rawtypes" })
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
(Class<?>) type, messageConverters.getConverters());
Object data = extractor.extractData(new FeignResponseAdapter(response));
return data;
}
throw new DecodeException("type is not an instance of Class: " + type);
if (type instanceof Class || type instanceof ParameterizedType) {
@SuppressWarnings({ "unchecked", "rawtypes" })
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
type, messageConverters.getConverters());
return extractor.extractData(new FeignResponseAdapter(response));
}
throw new DecodeException("type is not an instance of Class or ParameterizedType: " + type);
}
private class FeignResponseAdapter implements ClientHttpResponse {
private class FeignResponseAdapter implements ClientHttpResponse {
private final Response response;
private FeignResponseAdapter(Response response) {
......
package org.springframework.cloud.netflix.feign;
import static org.junit.Assert.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringDecoderTests.Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest", "spring.jmx.enabled=true" })
public class SpringDecoderTests extends FeignConfigurer {
@Value("${local.server.port}")
private int port = 0;
public TestClient testClient() {
return feign().target(TestClient.class, "http://localhost:"+port);
}
protected static interface TestClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
public Hello getHello();
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
public List<Hello> getHellos();
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
public List<String> getHelloStrings();
}
@Configuration
@EnableAutoConfiguration
@RestController
protected static class Application implements TestClient {
public Hello getHello() {
return new Hello("hello world 1");
}
public List<Hello> getHellos() {
ArrayList<Hello> hellos = new ArrayList<>();
hellos.add(new Hello("hello world 1"));
hellos.add(new Hello("oi terra 2"));
return hellos;
}
public List<String> getHelloStrings() {
ArrayList<String> hellos = new ArrayList<>();
hellos.add("hello world 1");
hellos.add("oi terra 2");
return hellos;
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).properties(
"spring.application.name=springdecodertest", "management.contextPath=/admin")
.run(args);
}
}
@Test
public void testSimpleType() {
Hello hello = testClient().getHello();
assertNotNull("hello was null", hello);
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
}
@Test
public void testUserParameterizedTypeDecode() {
List<Hello> hellos = testClient().getHellos();
assertNotNull("hellos was null", hellos);
assertEquals("hellos was not the right size", 2, hellos.size());
assertEquals("first hello didn't match", new Hello("hello world 1"), hellos.get(0));
}
@Test
public void testSimpleParameterizedTypeDecode() {
List<String> hellos = testClient().getHelloStrings();
assertNotNull("hellos was null", hellos);
assertEquals("hellos was not the right size", 2, hellos.size());
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Hello {
private String message;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment