diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml
index 1cbb774b..5107bd0b 100644
--- a/spring-cloud-netflix-core/pom.xml
+++ b/spring-cloud-netflix-core/pom.xml
@@ -114,6 +114,11 @@
feign-okhttp
true
+
+ io.github.openfeign
+ feign-java8
+ true
+
com.netflix.hystrix
hystrix-core
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java
index 79fa69ea..bcfb8eeb 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java
@@ -46,6 +46,7 @@ import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.hystrix.HystrixFeign;
+import feign.optionals.OptionalDecoder;
/**
* @author Dave Syer
@@ -69,7 +70,7 @@ public class FeignClientsConfiguration {
@Bean
@ConditionalOnMissingBean
public Decoder feignDecoder() {
- return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));
+ return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)));
}
@Bean
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java
index 1bbd6098..73c24b38 100644
--- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java
@@ -23,7 +23,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
-import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
import org.springframework.context.annotation.Configuration;
@@ -36,6 +35,7 @@ import feign.Feign;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
+import feign.optionals.OptionalDecoder;
import feign.slf4j.Slf4jLogger;
/**
@@ -51,7 +51,7 @@ public class EnableFeignClientsTests {
@Test
public void decoderDefaultCorrect() {
- ResponseEntityDecoder.class
+ OptionalDecoder.class
.cast(this.feignContext.getInstance("foo", Decoder.class));
}
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java
index 893c9642..bf07fddd 100644
--- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java
@@ -17,17 +17,12 @@
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
-import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
@@ -38,6 +33,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
import feign.Contract;
import feign.Feign;
import feign.Logger;
@@ -51,6 +50,7 @@ import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import feign.hystrix.HystrixFeign;
+import feign.optionals.OptionalDecoder;
import feign.slf4j.Slf4jLogger;
/**
@@ -79,7 +79,7 @@ public class FeignClientOverrideDefaultsTests {
@Test
public void overrideDecoder() {
Decoder.Default.class.cast(this.context.getInstance("foo", Decoder.class));
- ResponseEntityDecoder.class.cast(this.context.getInstance("bar", Decoder.class));
+ OptionalDecoder.class.cast(this.context.getInstance("bar", Decoder.class));
}
@Test
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java
index 82aa0d20..274d0eb6 100644
--- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java
@@ -16,14 +16,6 @@
package org.springframework.cloud.netflix.feign.valid;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -34,6 +26,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -76,6 +69,15 @@ import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
import feign.Client;
import feign.Feign;
import feign.Logger;
@@ -161,6 +163,9 @@ public class FeignClientTests {
@RequestMapping(method = RequestMethod.GET, path = "/hello")
Hello getHello();
+ @RequestMapping(method = RequestMethod.GET, path = "/hello")
+ Optional getOptionalHello();
+
@RequestMapping(method = RequestMethod.GET, path = "${feignClient.methodLevelRequestMappingPath}")
Hello getHelloUsingPropertyPlaceHolder();
@@ -240,6 +245,9 @@ public class FeignClientTests {
protected interface DecodingTestClient {
@RequestMapping(method = RequestMethod.GET, path = "/notFound")
ResponseEntity notFound();
+
+ @RequestMapping(method = RequestMethod.GET, path = "/notFound")
+ Optional optional();
}
@FeignClient(name = "localapp3", fallback = HystrixClientFallback.class)
@@ -518,6 +526,15 @@ public class FeignClientTests {
assertEquals("first hello didn't match", new Hello(HELLO_WORLD_1), hello);
}
+ @Test
+ public void testOptional() {
+ Optional hello = this.testClient.getOptionalHello();
+ assertThat(hello)
+ .isNotNull()
+ .isPresent()
+ .contains(new Hello(HELLO_WORLD_1));
+ }
+
@Test
public void testGenericType() {
List hellos = this.testClient.getHellos();
@@ -632,6 +649,12 @@ public class FeignClientTests {
assertNull("response body was not null", response.getBody());
}
+ @Test
+ public void testOptionalNotFound() {
+ Optional s = decodingTestClient.optional();
+ assertThat(s).isNotPresent();
+ }
+
@Test
public void testConvertingExpander() {
assertEquals(Arg.A.toString(), testClient.getToString(Arg.A));
diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml
index f1d23834..b4aec7c7 100644
--- a/spring-cloud-netflix-dependencies/pom.xml
+++ b/spring-cloud-netflix-dependencies/pom.xml
@@ -16,7 +16,7 @@
0.7.5
1.8.2
- 9.5.0
+ 9.5.1
1.5.12
2.2.2
0.10.1
@@ -281,6 +281,11 @@
feign-hystrix
${feign.version}
+
+ io.github.openfeign
+ feign-java8
+ ${feign.version}
+
io.github.openfeign
feign-okhttp
diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml
index 124e783d..8e52a353 100644
--- a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml
+++ b/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml
@@ -46,6 +46,10 @@
io.github.openfeign
feign-hystrix
+
+ io.github.openfeign
+ feign-java8
+
org.springframework.cloud
spring-cloud-starter-netflix-ribbon