adds support for response interceptor configuration. Fixes gh-802 (#804)

This commit is contained in:
Dominique Villard
2022-12-15 10:44:56 +01:00
committed by GitHub
parent 8a1f888aac
commit fead135d92
6 changed files with 71 additions and 2 deletions

View File

@@ -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

View File

@@ -32,6 +32,7 @@ import feign.Logger;
import feign.QueryMapEncoder;
import feign.Request;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.Target.HardCodedTarget;
import feign.codec.Decoder;
@@ -219,6 +220,10 @@ public class FeignClientFactoryBean
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);
@@ -277,6 +282,10 @@ public class FeignClientFactoryBean
}
}
if (config.getResponseInterceptor() != null) {
builder.responseInterceptor(getOrInstantiate(config.getResponseInterceptor()));
}
if (config.getDismiss404() != null) {
if (config.getDismiss404()) {
builder.dismiss404();

View File

@@ -28,6 +28,7 @@ import feign.ExceptionPropagationPolicy;
import feign.Logger;
import feign.QueryMapEncoder;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
@@ -126,6 +127,8 @@ public class FeignClientProperties {
private List<Class<RequestInterceptor>> requestInterceptors;
private Class<ResponseInterceptor> responseInterceptor;
private Map<String, Collection<String>> defaultRequestHeaders;
private Map<String, Collection<String>> defaultQueryParameters;
@@ -202,6 +205,14 @@ public class FeignClientProperties {
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;
}
@@ -311,6 +322,7 @@ public class FeignClientProperties {
&& 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)
@@ -325,8 +337,9 @@ public class FeignClientProperties {
@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);
}
}

View File

@@ -27,6 +27,7 @@ import feign.ExceptionPropagationPolicy;
import feign.Logger;
import feign.QueryMapEncoder;
import feign.RequestInterceptor;
import feign.ResponseInterceptor;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
@@ -60,6 +61,7 @@ class FeignClientConfigurationTests {
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();
@@ -82,6 +84,8 @@ class FeignClientConfigurationTests {
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());
@@ -103,6 +107,7 @@ class FeignClientConfigurationTests {
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();

View File

@@ -34,11 +34,13 @@ import java.util.stream.Stream;
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;
@@ -99,6 +101,8 @@ public class FeignClientUsingPropertiesTests {
private FeignClientFactoryBean barFactoryBean;
private FeignClientFactoryBean bazFactoryBean;
private FeignClientFactoryBean unwrapFactoryBean;
private FeignClientFactoryBean formFactoryBean;
@@ -116,6 +120,10 @@ public class 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);
@@ -143,6 +151,11 @@ public class FeignClientUsingPropertiesTests {
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);
@@ -164,6 +177,12 @@ public class FeignClientUsingPropertiesTests {
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);
@@ -298,6 +317,13 @@ public class FeignClientUsingPropertiesTests {
}
protected interface PingClient {
@GetMapping(path = "/ping")
String ping();
}
protected interface UnwrapClient {
@GetMapping(path = "/bar") // intentionally /bar
@@ -355,6 +381,11 @@ public class FeignClientUsingPropertiesTests {
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");
@@ -394,6 +425,15 @@ public class FeignClientUsingPropertiesTests {
}
public static class BazResponseInterceptor implements ResponseInterceptor {
@Override
public Object aroundDecode(InvocationContext invocationContext) {
return "baz";
}
}
public static class NoRetryer implements Retryer {
@Override

View File

@@ -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