diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java index b6a73935..c0140e84 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java @@ -5,8 +5,6 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.LinkedList; -import lombok.extern.slf4j.Slf4j; - import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; @@ -15,6 +13,7 @@ import org.springframework.util.MultiValueMap; import feign.FeignException; import feign.Response; import feign.codec.Decoder; +import lombok.extern.slf4j.Slf4j; /** * Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via @@ -34,19 +33,30 @@ public class ResponseEntityDecoder implements Decoder { public Object decode(final Response response, Type type) throws IOException, FeignException { - if (type instanceof ParameterizedType - && ((ParameterizedType) type).getRawType().equals(ResponseEntity.class)) { - + if (isParameterizeResponseEntity(type)) { type = ((ParameterizedType) type).getActualTypeArguments()[0]; Object decodedObject = decoder.decode(response, type); return createResponse(decodedObject, response); } + else if (isResponseEntity(type)) { + return createResponse(null, response); + } else { return decoder.decode(response, type); } } + private boolean isParameterizeResponseEntity(Type type) { + return type instanceof ParameterizedType + && ((ParameterizedType) type).getRawType().equals(ResponseEntity.class); + } + + private boolean isResponseEntity(Type type) { + + return type instanceof Class && type.equals(ResponseEntity.class); + } + @SuppressWarnings("unchecked") private ResponseEntity createResponse(Object instance, Response response) { 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 91aad97d..3ba3ccd5 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 @@ -48,6 +48,8 @@ import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +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.RequestHeader; @@ -110,6 +112,12 @@ public class FeignClientTests { @RequestMapping(method = RequestMethod.GET, value = "/hellos") HystrixCommand> getHellosHystrix(); + + @RequestMapping(method = RequestMethod.GET, value = "/noContent") + ResponseEntity noContent(); + + @RequestMapping(method = RequestMethod.HEAD, value = "/head") + ResponseEntity head(); } @FeignClient(serviceId = "localapp") @@ -179,6 +187,16 @@ public class FeignClientTests { return params; } + @RequestMapping(method = RequestMethod.GET, value = "/noContent") + ResponseEntity noContent() { + return ResponseEntity.noContent().build(); + } + + @RequestMapping(method = RequestMethod.HEAD, value = "/head") + ResponseEntity head() { + return ResponseEntity.ok().build(); + } + public static void main(String[] args) { new SpringApplicationBuilder(Application.class).properties( "spring.application.name=feignclienttest", @@ -259,6 +277,20 @@ public class FeignClientTests { assertEquals("hellos didn't match", hellos, getHelloList()); } + @Test + public void testNoContentResponse() { + ResponseEntity response = testClient.noContent(); + assertNotNull("response was null", response); + assertEquals("status code was wrong", HttpStatus.NO_CONTENT, response.getStatusCode()); + } + + @Test + public void testHeadResponse() { + ResponseEntity response = testClient.head(); + assertNotNull("response was null", response); + assertEquals("status code was wrong", HttpStatus.OK, response.getStatusCode()); + } + @Data @AllArgsConstructor @NoArgsConstructor