Commit 61bbca23 by Eko Kurniawan Khannedy Committed by Ryan Baxter

add encoder, decoder and contract to feign properties, so we can override the…

add encoder, decoder and contract to feign properties, so we can override the default value with properties (#2687)
parent a0821467
......@@ -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.
......
/*
* 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);
}
}
......
/*
* 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
\ No newline at end of file
feign.client.config.bar.readTimeout=1000
feign.client.config.form.encoder=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.FormEncoder
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment