Added support for MultipartFile (#66)
Fixes gh-62
### Notes
The solution is based on
```
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.3.0</version>
</dependency>
```
Class `feign.form.spring.SpringFormEncoder` was added inside `org.springframework.cloud.openfeign.support.SpringEncoder` because it's doesn't has some checks:
1. Check of `bodyType` on null.
`org.springframework.cloud.openfeign.support.SpringEncoder#encode` don't handle situation when `bodyType` is null.
2. No check for content type `multipart/form-data` in header.
`feign.form.FormEncoder` requires `multipart/form-data` in header for proper processing.
All this checks added and tests are passed.
This commit is contained in:
@@ -93,6 +93,10 @@
|
||||
<artifactId>feign-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign.form</groupId>
|
||||
<artifactId>feign-form-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -35,10 +36,12 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHeaders;
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHttpHeaders;
|
||||
@@ -51,6 +54,8 @@ public class SpringEncoder implements Encoder {
|
||||
|
||||
private static final Log log = LogFactory.getLog(SpringEncoder.class);
|
||||
|
||||
private final SpringFormEncoder springFormEncoder = new SpringFormEncoder();
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
@@ -71,6 +76,18 @@ public class SpringEncoder implements Encoder {
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
if (bodyType != null && bodyType.equals(MultipartFile.class)) {
|
||||
if (Objects.equals(requestContentType, MediaType.MULTIPART_FORM_DATA)) {
|
||||
springFormEncoder.encode(requestBody, bodyType, request);
|
||||
return;
|
||||
} else {
|
||||
String message = "Content-Type \"" + MediaType.MULTIPART_FORM_DATA +
|
||||
"\" not set for request body of type " +
|
||||
requestBody.getClass().getSimpleName();
|
||||
throw new EncodeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters
|
||||
.getObject().getConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
|
||||
@@ -40,9 +40,11 @@ import org.springframework.http.converter.AbstractGenericHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
@@ -50,6 +52,7 @@ import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -96,6 +99,31 @@ public class SpringEncoderTests {
|
||||
|
||||
assertThat("request charset is not null", request.charset(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test(expected = EncodeException.class)
|
||||
public void testMultipartFile1() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
|
||||
encoder.encode(multipartFile, MultipartFile.class, request);
|
||||
|
||||
assertThat("request charset is not null", request.charset(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipartFile2() {
|
||||
SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class);
|
||||
assertThat(encoder, is(notNullValue()));
|
||||
RequestTemplate request = new RequestTemplate();
|
||||
request = request.header("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE);
|
||||
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
|
||||
encoder.encode(multipartFile, MultipartFile.class, request);
|
||||
|
||||
assertThat("request charset is not null", request.charset(), is(nullValue()));
|
||||
}
|
||||
|
||||
class MediaTypeMatcher implements ArgumentMatcher<MediaType> {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<description>Spring Cloud OpenFeign Dependencies</description>
|
||||
<properties>
|
||||
<feign.version>9.5.1</feign.version>
|
||||
<feign-form.version>3.3.0</feign-form.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -33,6 +34,11 @@
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign.form</groupId>
|
||||
<artifactId>feign-form-spring</artifactId>
|
||||
<version>${feign-form.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user