Skip to content

Commit fead135

Browse files
authored
adds support for response interceptor configuration. Fixes gh-802 (#804)
1 parent 8a1f888 commit fead135

File tree

6 files changed

+71
-2
lines changed

6 files changed

+71
-2
lines changed

docs/src/main/asciidoc/spring-cloud-openfeign.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ spring:
206206
requestInterceptors:
207207
- com.example.FooRequestInterceptor
208208
- com.example.BarRequestInterceptor
209+
responseInterceptor: com.example.BazResponseInterceptor
209210
dismiss404: false
210211
encoder: com.example.SimpleEncoder
211212
decoder: com.example.SimpleDecoder

spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import feign.QueryMapEncoder;
3333
import feign.Request;
3434
import feign.RequestInterceptor;
35+
import feign.ResponseInterceptor;
3536
import feign.Retryer;
3637
import feign.Target.HardCodedTarget;
3738
import feign.codec.Decoder;
@@ -219,6 +220,10 @@ protected void configureUsingConfiguration(FeignClientFactory context, Feign.Bui
219220
AnnotationAwareOrderComparator.sort(interceptors);
220221
builder.requestInterceptors(interceptors);
221222
}
223+
ResponseInterceptor responseInterceptor = getInheritedAwareOptional(context, ResponseInterceptor.class);
224+
if (responseInterceptor != null) {
225+
builder.responseInterceptor(responseInterceptor);
226+
}
222227
QueryMapEncoder queryMapEncoder = getInheritedAwareOptional(context, QueryMapEncoder.class);
223228
if (queryMapEncoder != null) {
224229
builder.queryMapEncoder(queryMapEncoder);
@@ -277,6 +282,10 @@ protected void configureUsingProperties(FeignClientProperties.FeignClientConfigu
277282
}
278283
}
279284

285+
if (config.getResponseInterceptor() != null) {
286+
builder.responseInterceptor(getOrInstantiate(config.getResponseInterceptor()));
287+
}
288+
280289
if (config.getDismiss404() != null) {
281290
if (config.getDismiss404()) {
282291
builder.dismiss404();

spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientProperties.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import feign.Logger;
2929
import feign.QueryMapEncoder;
3030
import feign.RequestInterceptor;
31+
import feign.ResponseInterceptor;
3132
import feign.Retryer;
3233
import feign.codec.Decoder;
3334
import feign.codec.Encoder;
@@ -126,6 +127,8 @@ public static class FeignClientConfiguration {
126127

127128
private List<Class<RequestInterceptor>> requestInterceptors;
128129

130+
private Class<ResponseInterceptor> responseInterceptor;
131+
129132
private Map<String, Collection<String>> defaultRequestHeaders;
130133

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

208+
public Class<ResponseInterceptor> getResponseInterceptor() {
209+
return responseInterceptor;
210+
}
211+
212+
public void setResponseInterceptor(Class<ResponseInterceptor> responseInterceptor) {
213+
this.responseInterceptor = responseInterceptor;
214+
}
215+
205216
public Map<String, Collection<String>> getDefaultRequestHeaders() {
206217
return defaultRequestHeaders;
207218
}
@@ -311,6 +322,7 @@ public boolean equals(Object o) {
311322
&& Objects.equals(readTimeout, that.readTimeout) && Objects.equals(retryer, that.retryer)
312323
&& Objects.equals(errorDecoder, that.errorDecoder)
313324
&& Objects.equals(requestInterceptors, that.requestInterceptors)
325+
&& Objects.equals(responseInterceptor, that.responseInterceptor)
314326
&& Objects.equals(dismiss404, that.dismiss404) && Objects.equals(encoder, that.encoder)
315327
&& Objects.equals(decoder, that.decoder) && Objects.equals(contract, that.contract)
316328
&& Objects.equals(exceptionPropagationPolicy, that.exceptionPropagationPolicy)
@@ -325,8 +337,9 @@ public boolean equals(Object o) {
325337
@Override
326338
public int hashCode() {
327339
return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer, errorDecoder, requestInterceptors,
328-
dismiss404, encoder, decoder, contract, exceptionPropagationPolicy, defaultQueryParameters,
329-
defaultRequestHeaders, capabilities, queryMapEncoder, micrometer, followRedirects, url);
340+
responseInterceptor, dismiss404, encoder, decoder, contract, exceptionPropagationPolicy,
341+
defaultQueryParameters, defaultRequestHeaders, capabilities, queryMapEncoder, micrometer,
342+
followRedirects, url);
330343
}
331344

332345
}

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientConfigurationTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import feign.Logger;
2828
import feign.QueryMapEncoder;
2929
import feign.RequestInterceptor;
30+
import feign.ResponseInterceptor;
3031
import feign.Retryer;
3132
import feign.codec.Decoder;
3233
import feign.codec.Encoder;
@@ -60,6 +61,7 @@ void shouldDefaultToValuesWhenFieldsNotSet() {
6061
assertThat(config.getRetryer()).isNull();
6162
assertThat(config.getErrorDecoder()).isNull();
6263
assertThat(config.getRequestInterceptors()).isNull();
64+
assertThat(config.getResponseInterceptor()).isNull();
6365
assertThat(config.getDefaultRequestHeaders()).isNull();
6466
assertThat(config.getDefaultQueryParameters()).isNull();
6567
assertThat(config.getDismiss404()).isNull();
@@ -82,6 +84,8 @@ void shouldReturnValuesWhenSet() {
8284
config.setErrorDecoder(ErrorDecoder.class);
8385
List<Class<RequestInterceptor>> requestInterceptors = Lists.list(RequestInterceptor.class);
8486
config.setRequestInterceptors(requestInterceptors);
87+
Class<ResponseInterceptor> responseInterceptor = ResponseInterceptor.class;
88+
config.setResponseInterceptor(responseInterceptor);
8589
Map<String, Collection<String>> defaultRequestHeaders = Maps.newHashMap("default", Collections.emptyList());
8690
config.setDefaultRequestHeaders(defaultRequestHeaders);
8791
Map<String, Collection<String>> defaultQueryParameters = Maps.newHashMap("default", Collections.emptyList());
@@ -103,6 +107,7 @@ void shouldReturnValuesWhenSet() {
103107
assertThat(config.getRetryer()).isSameAs(Retryer.class);
104108
assertThat(config.getErrorDecoder()).isSameAs(ErrorDecoder.class);
105109
assertThat(config.getRequestInterceptors()).isSameAs(requestInterceptors);
110+
assertThat(config.getResponseInterceptor()).isSameAs(responseInterceptor);
106111
assertThat(config.getDefaultRequestHeaders()).isSameAs(defaultRequestHeaders);
107112
assertThat(config.getDefaultQueryParameters()).isSameAs(defaultQueryParameters);
108113
assertThat(config.getDismiss404()).isTrue();

spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@
3434

3535
import feign.Capability;
3636
import feign.Feign;
37+
import feign.InvocationContext;
3738
import feign.InvocationHandlerFactory;
3839
import feign.QueryMapEncoder;
3940
import feign.Request;
4041
import feign.RequestInterceptor;
4142
import feign.RequestTemplate;
43+
import feign.ResponseInterceptor;
4244
import feign.RetryableException;
4345
import feign.Retryer;
4446
import feign.codec.EncodeException;
@@ -99,6 +101,8 @@ public class FeignClientUsingPropertiesTests {
99101

100102
private FeignClientFactoryBean barFactoryBean;
101103

104+
private FeignClientFactoryBean bazFactoryBean;
105+
102106
private FeignClientFactoryBean unwrapFactoryBean;
103107

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

123+
bazFactoryBean = new FeignClientFactoryBean();
124+
bazFactoryBean.setContextId("baz");
125+
bazFactoryBean.setType(FeignClientFactoryBean.class);
126+
119127
unwrapFactoryBean = new FeignClientFactoryBean();
120128
unwrapFactoryBean.setContextId("unwrap");
121129
unwrapFactoryBean.setType(FeignClientFactoryBean.class);
@@ -143,6 +151,11 @@ public BarClient barClient() {
143151
return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + port);
144152
}
145153

154+
public PingClient pingClient() {
155+
bazFactoryBean.setApplicationContext(applicationContext);
156+
return bazFactoryBean.feign(context).target(PingClient.class, "http://localhost:" + port);
157+
}
158+
146159
public UnwrapClient unwrapClient() {
147160
unwrapFactoryBean.setApplicationContext(applicationContext);
148161
return unwrapFactoryBean.feign(context).target(UnwrapClient.class, "http://localhost:" + port);
@@ -164,6 +177,12 @@ public void testBar() {
164177
assertThatThrownBy(() -> barClient().bar()).isInstanceOf(RetryableException.class);
165178
}
166179

180+
@Test
181+
public void testBaz() {
182+
String response = pingClient().ping();
183+
assertThat(response).isEqualTo("baz");
184+
}
185+
167186
@Test
168187
public void testUnwrap() throws Exception {
169188
assertThatThrownBy(() -> unwrapClient().unwrap()).isInstanceOf(SocketTimeoutException.class);
@@ -298,6 +317,13 @@ protected interface BarClient {
298317

299318
}
300319

320+
protected interface PingClient {
321+
322+
@GetMapping(path = "/ping")
323+
String ping();
324+
325+
}
326+
301327
protected interface UnwrapClient {
302328

303329
@GetMapping(path = "/bar") // intentionally /bar
@@ -355,6 +381,11 @@ public String bar() throws InterruptedException {
355381
return "OK";
356382
}
357383

384+
@GetMapping(path = "/ping")
385+
public String ping() {
386+
return "pong";
387+
}
388+
358389
@PostMapping(path = "/form", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
359390
public String form(HttpServletRequest request) {
360391
return request.getParameter("form");
@@ -394,6 +425,15 @@ public void apply(RequestTemplate template) {
394425

395426
}
396427

428+
public static class BazResponseInterceptor implements ResponseInterceptor {
429+
430+
@Override
431+
public Object aroundDecode(InvocationContext invocationContext) {
432+
return "baz";
433+
}
434+
435+
}
436+
397437
public static class NoRetryer implements Retryer {
398438

399439
@Override

spring-cloud-openfeign-core/src/test/resources/feign-properties.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ spring.cloud.openfeign.client.config.default.capabilities=org.springframework.cl
1212
spring.cloud.openfeign.client.config.default.queryMapEncoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.NoOpQueryMapEncoder
1313
spring.cloud.openfeign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FooRequestInterceptor
1414
spring.cloud.openfeign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BarRequestInterceptor
15+
spring.cloud.openfeign.client.config.baz.responseInterceptor=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BazResponseInterceptor
1516
spring.cloud.openfeign.client.config.singleValue.defaultRequestHeaders[singleValueHeaders]=header
1617
spring.cloud.openfeign.client.config.singleValue.defaultQueryParameters[singleValueParameters]=parameter
1718
spring.cloud.openfeign.client.config.multipleValue.defaultRequestHeaders[multipleValueHeaders]=header1,header2

0 commit comments

Comments
 (0)