Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/spring-cloud-openfeign.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ spring:
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
responseInterceptor: com.example.BazResponseInterceptor
dismiss404: false
encoder: com.example.SimpleEncoder
decoder: com.example.SimpleDecoder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import feign.QueryMapEncoder;
import feign.Request;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.Target.HardCodedTarget;
import feign.codec.Decoder;
Expand Down Expand Up @@ -219,6 +220,10 @@ protected void configureUsingConfiguration(FeignClientFactory context, Feign.Bui
AnnotationAwareOrderComparator.sort(interceptors);
builder.requestInterceptors(interceptors);
}
ResponseInterceptor responseInterceptor = getInheritedAwareOptional(context, ResponseInterceptor.class);
if (responseInterceptor != null) {
builder.responseInterceptor(responseInterceptor);
}
QueryMapEncoder queryMapEncoder = getInheritedAwareOptional(context, QueryMapEncoder.class);
if (queryMapEncoder != null) {
builder.queryMapEncoder(queryMapEncoder);
Expand Down Expand Up @@ -277,6 +282,10 @@ protected void configureUsingProperties(FeignClientProperties.FeignClientConfigu
}
}

if (config.getResponseInterceptor() != null) {
builder.responseInterceptor(getOrInstantiate(config.getResponseInterceptor()));
}

if (config.getDismiss404() != null) {
if (config.getDismiss404()) {
builder.dismiss404();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import feign.Logger;
import feign.QueryMapEncoder;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
Expand Down Expand Up @@ -126,6 +127,8 @@ public static class FeignClientConfiguration {

private List<Class<RequestInterceptor>> requestInterceptors;

private Class<ResponseInterceptor> responseInterceptor;

private Map<String, Collection<String>> defaultRequestHeaders;

private Map<String, Collection<String>> defaultQueryParameters;
Expand Down Expand Up @@ -202,6 +205,14 @@ public void setRequestInterceptors(List<Class<RequestInterceptor>> requestInterc
this.requestInterceptors = requestInterceptors;
}

public Class<ResponseInterceptor> getResponseInterceptor() {
return responseInterceptor;
}

public void setResponseInterceptor(Class<ResponseInterceptor> responseInterceptor) {
this.responseInterceptor = responseInterceptor;
}

public Map<String, Collection<String>> getDefaultRequestHeaders() {
return defaultRequestHeaders;
}
Expand Down Expand Up @@ -311,6 +322,7 @@ public boolean equals(Object o) {
&& Objects.equals(readTimeout, that.readTimeout) && Objects.equals(retryer, that.retryer)
&& Objects.equals(errorDecoder, that.errorDecoder)
&& Objects.equals(requestInterceptors, that.requestInterceptors)
&& Objects.equals(responseInterceptor, that.responseInterceptor)
&& Objects.equals(dismiss404, that.dismiss404) && Objects.equals(encoder, that.encoder)
&& Objects.equals(decoder, that.decoder) && Objects.equals(contract, that.contract)
&& Objects.equals(exceptionPropagationPolicy, that.exceptionPropagationPolicy)
Expand All @@ -325,8 +337,9 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer, errorDecoder, requestInterceptors,
dismiss404, encoder, decoder, contract, exceptionPropagationPolicy, defaultQueryParameters,
defaultRequestHeaders, capabilities, queryMapEncoder, micrometer, followRedirects, url);
responseInterceptor, dismiss404, encoder, decoder, contract, exceptionPropagationPolicy,
defaultQueryParameters, defaultRequestHeaders, capabilities, queryMapEncoder, micrometer,
followRedirects, url);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import feign.Logger;
import feign.QueryMapEncoder;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
Expand Down Expand Up @@ -60,6 +61,7 @@ void shouldDefaultToValuesWhenFieldsNotSet() {
assertThat(config.getRetryer()).isNull();
assertThat(config.getErrorDecoder()).isNull();
assertThat(config.getRequestInterceptors()).isNull();
assertThat(config.getResponseInterceptor()).isNull();
assertThat(config.getDefaultRequestHeaders()).isNull();
assertThat(config.getDefaultQueryParameters()).isNull();
assertThat(config.getDismiss404()).isNull();
Expand All @@ -82,6 +84,8 @@ void shouldReturnValuesWhenSet() {
config.setErrorDecoder(ErrorDecoder.class);
List<Class<RequestInterceptor>> requestInterceptors = Lists.list(RequestInterceptor.class);
config.setRequestInterceptors(requestInterceptors);
Class<ResponseInterceptor> responseInterceptor = ResponseInterceptor.class;
config.setResponseInterceptor(responseInterceptor);
Map<String, Collection<String>> defaultRequestHeaders = Maps.newHashMap("default", Collections.emptyList());
config.setDefaultRequestHeaders(defaultRequestHeaders);
Map<String, Collection<String>> defaultQueryParameters = Maps.newHashMap("default", Collections.emptyList());
Expand All @@ -103,6 +107,7 @@ void shouldReturnValuesWhenSet() {
assertThat(config.getRetryer()).isSameAs(Retryer.class);
assertThat(config.getErrorDecoder()).isSameAs(ErrorDecoder.class);
assertThat(config.getRequestInterceptors()).isSameAs(requestInterceptors);
assertThat(config.getResponseInterceptor()).isSameAs(responseInterceptor);
assertThat(config.getDefaultRequestHeaders()).isSameAs(defaultRequestHeaders);
assertThat(config.getDefaultQueryParameters()).isSameAs(defaultQueryParameters);
assertThat(config.getDismiss404()).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@

import feign.Capability;
import feign.Feign;
import feign.InvocationContext;
import feign.InvocationHandlerFactory;
import feign.QueryMapEncoder;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.ResponseInterceptor;
import feign.RetryableException;
import feign.Retryer;
import feign.codec.EncodeException;
Expand Down Expand Up @@ -99,6 +101,8 @@ public class FeignClientUsingPropertiesTests {

private FeignClientFactoryBean barFactoryBean;

private FeignClientFactoryBean bazFactoryBean;

private FeignClientFactoryBean unwrapFactoryBean;

private FeignClientFactoryBean formFactoryBean;
Expand All @@ -116,6 +120,10 @@ public FeignClientUsingPropertiesTests() {
barFactoryBean.setContextId("bar");
barFactoryBean.setType(FeignClientFactoryBean.class);

bazFactoryBean = new FeignClientFactoryBean();
bazFactoryBean.setContextId("baz");
bazFactoryBean.setType(FeignClientFactoryBean.class);

unwrapFactoryBean = new FeignClientFactoryBean();
unwrapFactoryBean.setContextId("unwrap");
unwrapFactoryBean.setType(FeignClientFactoryBean.class);
Expand Down Expand Up @@ -143,6 +151,11 @@ public BarClient barClient() {
return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + port);
}

public PingClient pingClient() {
bazFactoryBean.setApplicationContext(applicationContext);
return bazFactoryBean.feign(context).target(PingClient.class, "http://localhost:" + port);
}

public UnwrapClient unwrapClient() {
unwrapFactoryBean.setApplicationContext(applicationContext);
return unwrapFactoryBean.feign(context).target(UnwrapClient.class, "http://localhost:" + port);
Expand All @@ -164,6 +177,12 @@ public void testBar() {
assertThatThrownBy(() -> barClient().bar()).isInstanceOf(RetryableException.class);
}

@Test
public void testBaz() {
String response = pingClient().ping();
assertThat(response).isEqualTo("baz");
}

@Test
public void testUnwrap() throws Exception {
assertThatThrownBy(() -> unwrapClient().unwrap()).isInstanceOf(SocketTimeoutException.class);
Expand Down Expand Up @@ -298,6 +317,13 @@ protected interface BarClient {

}

protected interface PingClient {

@GetMapping(path = "/ping")
String ping();

}

protected interface UnwrapClient {

@GetMapping(path = "/bar") // intentionally /bar
Expand Down Expand Up @@ -355,6 +381,11 @@ public String bar() throws InterruptedException {
return "OK";
}

@GetMapping(path = "/ping")
public String ping() {
return "pong";
}

@PostMapping(path = "/form", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String form(HttpServletRequest request) {
return request.getParameter("form");
Expand Down Expand Up @@ -394,6 +425,15 @@ public void apply(RequestTemplate template) {

}

public static class BazResponseInterceptor implements ResponseInterceptor {

@Override
public Object aroundDecode(InvocationContext invocationContext) {
return "baz";
}

}

public static class NoRetryer implements Retryer {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ spring.cloud.openfeign.client.config.default.capabilities=org.springframework.cl
spring.cloud.openfeign.client.config.default.queryMapEncoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.NoOpQueryMapEncoder
spring.cloud.openfeign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FooRequestInterceptor
spring.cloud.openfeign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BarRequestInterceptor
spring.cloud.openfeign.client.config.baz.responseInterceptor=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BazResponseInterceptor
spring.cloud.openfeign.client.config.singleValue.defaultRequestHeaders[singleValueHeaders]=header
spring.cloud.openfeign.client.config.singleValue.defaultQueryParameters[singleValueParameters]=parameter
spring.cloud.openfeign.client.config.multipleValue.defaultRequestHeaders[multipleValueHeaders]=header1,header2
Expand Down