add encoder, decoder and contract to feign properties, so we can override the default value with properties (#2687)
This commit is contained in:
committed by
Ryan Baxter
parent
a082146715
commit
61bbca23ff
@@ -1131,6 +1131,9 @@ feign:
|
||||
- com.example.FooRequestInterceptor
|
||||
- com.example.BarRequestInterceptor
|
||||
decode404: false
|
||||
encoder: com.example.SimpleEncoder
|
||||
decoder: com.example.SimpleDecoder
|
||||
contract: com.example.SimpleContract
|
||||
----
|
||||
|
||||
Default configurations can be specified in the `@EnableFeignClients` attribute `defaultConfiguration` in a similar manner as described above. The difference is that this configuration will apply to _all_ feign clients.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -179,6 +179,18 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
builder.decode404();
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.nonNull(config.getEncoder())) {
|
||||
builder.encoder(getOrInstantiate(config.getEncoder()));
|
||||
}
|
||||
|
||||
if (Objects.nonNull(config.getDecoder())) {
|
||||
builder.decoder(getOrInstantiate(config.getDecoder()));
|
||||
}
|
||||
|
||||
if (Objects.nonNull(config.getContract())) {
|
||||
builder.contract(getOrInstantiate(config.getContract()));
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getOrInstantiate(Class<T> tClass) {
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Logger;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.Retryer;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@@ -93,6 +96,12 @@ public class FeignClientProperties {
|
||||
|
||||
private Boolean decode404;
|
||||
|
||||
private Class<Decoder> decoder;
|
||||
|
||||
private Class<Encoder> encoder;
|
||||
|
||||
private Class<Contract> contract;
|
||||
|
||||
public Logger.Level getLoggerLevel() {
|
||||
return loggerLevel;
|
||||
}
|
||||
@@ -149,6 +158,30 @@ public class FeignClientProperties {
|
||||
this.decode404 = decode404;
|
||||
}
|
||||
|
||||
public Class<Decoder> getDecoder() {
|
||||
return decoder;
|
||||
}
|
||||
|
||||
public void setDecoder(Class<Decoder> decoder) {
|
||||
this.decoder = decoder;
|
||||
}
|
||||
|
||||
public Class<Encoder> getEncoder() {
|
||||
return encoder;
|
||||
}
|
||||
|
||||
public void setEncoder(Class<Encoder> encoder) {
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
public Class<Contract> getContract() {
|
||||
return contract;
|
||||
}
|
||||
|
||||
public void setContract(Class<Contract> contract) {
|
||||
this.contract = contract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -160,13 +193,16 @@ public class FeignClientProperties {
|
||||
Objects.equals(retryer, that.retryer) &&
|
||||
Objects.equals(errorDecoder, that.errorDecoder) &&
|
||||
Objects.equals(requestInterceptors, that.requestInterceptors) &&
|
||||
Objects.equals(decode404, that.decode404);
|
||||
Objects.equals(decode404, that.decode404) &&
|
||||
Objects.equals(encoder, that.encoder) &&
|
||||
Objects.equals(decoder, that.decoder) &&
|
||||
Objects.equals(contract, that.contract);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer,
|
||||
errorDecoder, requestInterceptors, decode404);
|
||||
errorDecoder, requestInterceptors, decode404, encoder, decoder, contract);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,8 @@ import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.RetryableException;
|
||||
import feign.Retryer;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -30,6 +32,8 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -38,8 +42,11 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
@@ -64,6 +71,8 @@ public class FeignClientUsingPropertiesTests {
|
||||
|
||||
private FeignClientFactoryBean barFactoryBean;
|
||||
|
||||
private FeignClientFactoryBean formFactoryBean;
|
||||
|
||||
public FeignClientUsingPropertiesTests() {
|
||||
fooFactoryBean = new FeignClientFactoryBean();
|
||||
fooFactoryBean.setName("foo");
|
||||
@@ -72,6 +81,10 @@ public class FeignClientUsingPropertiesTests {
|
||||
barFactoryBean = new FeignClientFactoryBean();
|
||||
barFactoryBean.setName("bar");
|
||||
barFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
|
||||
formFactoryBean = new FeignClientFactoryBean();
|
||||
formFactoryBean.setName("form");
|
||||
formFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
}
|
||||
|
||||
public FooClient fooClient() {
|
||||
@@ -84,10 +97,15 @@ public class FeignClientUsingPropertiesTests {
|
||||
return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
public FormClient formClient() {
|
||||
formFactoryBean.setApplicationContext(applicationContext);
|
||||
return formFactoryBean.feign(context).target(FormClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFoo() {
|
||||
String response = fooClient().foo();
|
||||
assertNotNull("OK", response);
|
||||
assertEquals("OK", response);
|
||||
}
|
||||
|
||||
@Test(expected = RetryableException.class)
|
||||
@@ -96,6 +114,13 @@ public class FeignClientUsingPropertiesTests {
|
||||
fail("it should timeout");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForm() {
|
||||
Map<String, String> request = Collections.singletonMap("form", "Data");
|
||||
String response = formClient().form(request);
|
||||
assertEquals("Data", response);
|
||||
}
|
||||
|
||||
protected interface FooClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/foo")
|
||||
@@ -108,6 +133,14 @@ public class FeignClientUsingPropertiesTests {
|
||||
String bar();
|
||||
}
|
||||
|
||||
protected interface FormClient {
|
||||
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
String form(Map<String, String> form);
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@@ -129,6 +162,12 @@ public class FeignClientUsingPropertiesTests {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public String form(HttpServletRequest request) {
|
||||
return request.getParameter("form");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FooRequestInterceptor implements RequestInterceptor {
|
||||
@@ -161,4 +200,19 @@ public class FeignClientUsingPropertiesTests {
|
||||
public static class DefaultErrorDecoder extends ErrorDecoder.Default {
|
||||
}
|
||||
|
||||
public static class FormEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public void encode(Object o, Type type, RequestTemplate requestTemplate) throws EncodeException {
|
||||
Map<String, String> form = (Map<String, String>) o;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
form.forEach((key, value) -> {
|
||||
builder.append(key + "=" + value + "&");
|
||||
});
|
||||
|
||||
requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
requestTemplate.body(builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,4 +16,6 @@ feign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.netflix
|
||||
feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.BarRequestInterceptor
|
||||
|
||||
feign.client.config.bar.connectTimeout=1000
|
||||
feign.client.config.bar.readTimeout=1000
|
||||
feign.client.config.bar.readTimeout=1000
|
||||
|
||||
feign.client.config.form.encoder=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.FormEncoder
|
||||
Reference in New Issue
Block a user