Commit 2a9a62d0 by Ryan Baxter Committed by GitHub

Merge pull request #1926 from TheSentinel454/issues_1676_wildcard_type_support

Add support for Wildcard Types in Feign Client. Fixes gh-1676
parents 377bccf1 189d926c
...@@ -22,6 +22,7 @@ import java.io.IOException; ...@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
...@@ -47,9 +48,10 @@ public class SpringDecoder implements Decoder { ...@@ -47,9 +48,10 @@ public class SpringDecoder implements Decoder {
} }
@Override @Override
public Object decode(final Response response, Type type) throws IOException, public Object decode(final Response response, Type type)
FeignException { throws IOException, FeignException {
if (type instanceof Class || type instanceof ParameterizedType) { if (type instanceof Class || type instanceof ParameterizedType
|| type instanceof WildcardType) {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor( HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
type, this.messageConverters.getObject().getConverters()); type, this.messageConverters.getObject().getConverters());
......
...@@ -19,9 +19,11 @@ package org.springframework.cloud.netflix.feign; ...@@ -19,9 +19,11 @@ package org.springframework.cloud.netflix.feign;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -36,6 +38,7 @@ import org.springframework.http.HttpStatus; ...@@ -36,6 +38,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -109,6 +112,19 @@ public class SpringDecoderTests extends FeignClientFactoryBean { ...@@ -109,6 +112,19 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
} }
@Test @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() { public void testResponseEntityVoid() {
ResponseEntity<Void> response = testClient().getHelloVoid(); ResponseEntity<Void> response = testClient().getHelloVoid();
assertNotNull("response was null", response); assertNotNull("response was null", response);
...@@ -156,6 +172,9 @@ public class SpringDecoderTests extends FeignClientFactoryBean { ...@@ -156,6 +172,9 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@RequestMapping(method = RequestMethod.GET, value = "/hellonotfound") @RequestMapping(method = RequestMethod.GET, value = "/hellonotfound")
ResponseEntity<String> getNotFound(); ResponseEntity<String> getNotFound();
@GetMapping("/helloWildcard")
ResponseEntity<?> getWildcard();
} }
@Configuration @Configuration
...@@ -199,6 +218,11 @@ public class SpringDecoderTests extends FeignClientFactoryBean { ...@@ -199,6 +218,11 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null); 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) { public static void main(String[] args) {
new SpringApplicationBuilder(Application.class) new SpringApplicationBuilder(Application.class)
.properties("spring.application.name=springdecodertest", .properties("spring.application.name=springdecodertest",
......
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