Add support for Wildcard Types in Feign Client. Fixes gh-1676
This commit is contained in:
@@ -16,13 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -30,10 +27,13 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.HttpMessageConverterExtractor;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.WildcardType;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -49,7 +49,7 @@ public class SpringDecoder implements Decoder {
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
FeignException {
|
||||
if (type instanceof Class || type instanceof ParameterizedType) {
|
||||
if (type instanceof Class || type instanceof ParameterizedType || type instanceof WildcardType) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, this.messageConverters.getObject().getConverters());
|
||||
|
||||
@@ -16,13 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -36,13 +32,16 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -108,6 +107,19 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testWildcardTypeDecode() {
|
||||
ResponseEntity<?> wildcard = testClient().getWildcard();
|
||||
assertNotNull("wildcard was null", wildcard);
|
||||
assertEquals("wrong status code", HttpStatus.OK, wildcard.getStatusCode());
|
||||
Object wildcardBody = wildcard.getBody();
|
||||
assertNotNull("wildcardBody was null", wildcardBody);
|
||||
assertTrue("wildcard not an instance of Map", wildcardBody instanceof Map);
|
||||
Map<String, String> hello = (Map<String, String>) wildcardBody;
|
||||
assertEquals("first hello didn't match", "wildcard", hello.get("message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseEntityVoid() {
|
||||
ResponseEntity<Void> response = testClient().getHelloVoid();
|
||||
@@ -156,6 +168,9 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellonotfound")
|
||||
ResponseEntity<String> getNotFound();
|
||||
|
||||
@GetMapping("/helloWildcard")
|
||||
ResponseEntity<?> getWildcard();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -199,6 +214,11 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<?> getWildcard() {
|
||||
return ResponseEntity.ok(new Hello("wildcard"));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class)
|
||||
.properties("spring.application.name=springdecodertest",
|
||||
|
||||
Reference in New Issue
Block a user