diff --git a/spring-cloud/spring-cloud-openfeign/pom.xml b/spring-cloud/spring-cloud-openfeign/pom.xml
index c1f3f2dc30..bdde46fe96 100644
--- a/spring-cloud/spring-cloud-openfeign/pom.xml
+++ b/spring-cloud/spring-cloud-openfeign/pom.xml
@@ -37,12 +37,24 @@
io.github.openfeign
feign-okhttp
-
+
org.springframework.boot
spring-boot-starter-web
+
+
+ io.github.openfeign.form
+ feign-form
+ 3.8.0
+
+
+ io.github.openfeign.form
+ feign-form-spring
+ 3.8.0
+
+
org.springframework.boot
spring-boot-starter-test
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java
new file mode 100644
index 0000000000..64ff21bb7d
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java
@@ -0,0 +1,28 @@
+package com.baeldung.cloud.openfeign.fileupload.config;
+
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.openfeign.support.SpringEncoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Scope;
+import org.springframework.web.client.RestTemplate;
+
+import feign.codec.Encoder;
+import feign.form.spring.SpringFormEncoder;
+
+@Configuration
+public class FeignSupportConfig {
+ @Bean
+ @Primary
+ @Scope("prototype")
+ public Encoder multipartFormEncoder() {
+ return new SpringFormEncoder(new SpringEncoder(new ObjectFactory() {
+ @Override
+ public HttpMessageConverters getObject() {
+ return new HttpMessageConverters(new RestTemplate().getMessageConverters());
+ }
+ }));
+ }
+}
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java
new file mode 100644
index 0000000000..ebdf7ff6c8
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java
@@ -0,0 +1,28 @@
+package com.baeldung.cloud.openfeign.fileupload.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.baeldung.cloud.openfeign.fileupload.service.UploadService;
+
+@RestController
+public class FileController {
+
+ @Autowired
+ private UploadService service;
+
+ @PostMapping(value = "/upload")
+ public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
+ return service.uploadFile(file);
+ }
+
+ @PostMapping(value = "/upload-mannual-client")
+ public boolean handleFileUploadWithManualClient(
+ @RequestPart(value = "file") MultipartFile file) {
+ return service.uploadFileWithManualClient(file);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java
new file mode 100644
index 0000000000..63d17130e9
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java
@@ -0,0 +1,15 @@
+package com.baeldung.cloud.openfeign.fileupload.service;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.baeldung.cloud.openfeign.fileupload.config.FeignSupportConfig;
+
+@FeignClient(name = "file", url = "http://localhost:8081", configuration = FeignSupportConfig.class)
+public interface UploadClient {
+ @PostMapping(value = "/upload-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ String fileUpload(@RequestPart(value = "file") MultipartFile file);
+}
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java
new file mode 100644
index 0000000000..26e658a7f0
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java
@@ -0,0 +1,16 @@
+package com.baeldung.cloud.openfeign.fileupload.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+import feign.Response;
+
+public interface UploadResource {
+
+ @RequestLine("POST /upload-file")
+ @Headers("Content-Type: multipart/form-data")
+ Response uploadFile(@Param("file") MultipartFile file);
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java
new file mode 100644
index 0000000000..7dd7f5a89c
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java
@@ -0,0 +1,29 @@
+package com.baeldung.cloud.openfeign.fileupload.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import feign.Feign;
+import feign.Response;
+import feign.form.spring.SpringFormEncoder;
+
+@Service
+public class UploadService {
+ private static final String HTTP_FILE_UPLOAD_URL = "http://localhost:8081";
+
+ @Autowired
+ private UploadClient client;
+
+ public boolean uploadFileWithManualClient(MultipartFile file) {
+ UploadResource fileUploadResource = Feign.builder().encoder(new SpringFormEncoder())
+ .target(UploadResource.class, HTTP_FILE_UPLOAD_URL);
+ Response response = fileUploadResource.uploadFile(file);
+ return response.status() == 200;
+ }
+
+ public String uploadFile(MultipartFile file) {
+ return client.fileUpload(file);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-openfeign/src/main/resources/fileupload.txt b/spring-cloud/spring-cloud-openfeign/src/main/resources/fileupload.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java
new file mode 100644
index 0000000000..f558e07491
--- /dev/null
+++ b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.cloud.openfeign;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.baeldung.cloud.openfeign.fileupload.service.UploadService;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class OpenFeignFileUploadLiveTest {
+
+ @Autowired
+ private UploadService uploadService;
+
+ private static String FILE_NAME = "fileupload.txt";
+
+ @Test
+ public void whenFeignBuilder_thenFileUploadSuccess() throws IOException {
+ ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+ File file = new File(classloader.getResource(FILE_NAME).getFile());
+ Assert.assertTrue(file.exists());
+ FileInputStream input = new FileInputStream(file);
+ MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain",
+ IOUtils.toByteArray(input));
+ Assert.assertTrue(uploadService.uploadFileWithManualClient(multipartFile));
+ }
+
+ @Test
+ public void whenAnnotatedFeignClient_thenFileUploadSuccess() throws IOException {
+ ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+ File file = new File(classloader.getResource(FILE_NAME).getFile());
+ Assert.assertTrue(file.exists());
+ FileInputStream input = new FileInputStream(file);
+ MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain",
+ IOUtils.toByteArray(input));
+ String uploadFile = uploadService.uploadFile(multipartFile);
+ Assert.assertNotNull(uploadFile);
+ }
+}