1. Overview
1.概述
In this tutorial, we’ll demonstrate how to upload a file using Open Feign. Feign is a powerful tool for microservice developers to communicate via REST API with other microservices in a declarative manner.
在本教程中,我们将演示如何使用Open Feign上传文件。Feign是一个强大的工具,供微服务开发人员通过REST API与其他微服务以声明的方式进行通信。
2. Prerequisite
2.先决条件
Let’s assume that a RESTful web service is exposed for a file upload, and given below are the details:
让我们假设一个RESTful Web服务被暴露出来,用于文件上传,下面给出了细节。
POST http://localhost:8081/upload-file
So, to explain the file upload via Feign client, we’ll call the exposed web service API as shown below:
因此,为了解释通过Feign客户端上传文件,我们将调用暴露的网络服务API,如下所示。
@PostMapping(value = "/upload-file")
public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
// File upload logic
}
3. Dependencies
3.依赖性
To support the application/x-www-form-urlencoded and multipart/form-data encoding types for the file upload, we’ll need feign-core, feign-form, and feign-form-spring modules.
为了支持文件上传的application/x-www-form-urlencoded和multipart/form-data编码类型,我们需要feign-core、feign-form、和feign-form-spring>模块。
Therefore, we’ll add the following dependencies to Maven:
因此,我们要向Maven添加以下依赖项。
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.12</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.8.0</version>
</dependency>
We can also use spring-cloud-starter-openfeign which has feign-core internally:
我们也可以使用spring-cloud-starter-openfeign,它内部有feign-core。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.0</version>
</dependency>
4. Configuration
4.配置
Let’s add @EnableFeignClients to our main class. You can visit spring cloud open feign tutorial for more details:
让我们把@EnableFeignClients添加到我们的主类中。你可以访问spring cloud open feign教程了解更多细节。
@SpringBootApplication
@EnableFeignClients
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
@EnableFeignClients annotation allows component scanning for the interfaces that are declared as Feign clients.
@EnableFeignClients注解允许组件扫描被声明为Feign客户端的接口。
5. File Upload via Feign Client
5.通过Feign客户端上传文件
5.1. Via Annotated Client
5.1.通过注释的客户端
Let’s create the required encoder for the annotated @FeignClient class:
让我们为注解的@FeignClient类创建所需的编码器。
public class FeignSupportConfig {
@Bean
public Encoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(new ObjectFactory<HttpMessageConverters>() {
@Override
public HttpMessageConverters getObject() throws BeansException {
return new HttpMessageConverters(new RestTemplate().getMessageConverters());
}
}));
}
}
Note that FeignSupportConfig does not need to be annotated with @Configuration.
请注意,FeignSupportConfig不需要用@Configuration.来注释。
Now, let’s create an interface and annotate it with @FeignClient. We’ll also add the name and configuration attributes with their corresponding values:
现在,让我们创建一个接口,并用@FeignClient来注释它。我们还将添加name和configuration属性以及它们相应的值。
@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);
}
The UploadClient points to the API mentioned in the prerequisite.
UploadClient指向先决条件中提到的API。
While working with Hystrix, we’ll use the fallback attribute to add as an alternative. This is done when the upload API fails.
在使用Hystrix时,我们将使用fallback属性来添加作为替代。这是在上传API失败时进行的.。
Now our @FeignClient will look like this:
现在我们的@FeignClient将看起来像这样。
@FeignClient(name = "file", url = "http://localhost:8081", fallback = UploadFallback.class, configuration = FeignSupportConfig.class)
And finally, we can call UploadClient directly from the service layer:
最后,我们可以直接从服务层调用UploadClient。
public String uploadFile(MultipartFile file) {
return client.fileUpload(file);
}
5.2. Via Feign.builder
5.2.通过Feign.builder
In some cases, our Feign Clients need to be customized, which is not possible in the annotation manner as described above. In such a case, we create clients using the Feign.builder() API.
在某些情况下,我们的Feign客户端需要被定制,这在上面描述的注释方式中是不可能的。在这种情况下,我们使用Feign.builder() API创建客户端。
Let’s build a proxy interface containing a file upload method targeted to the REST API for the file upload:
让我们建立一个代理接口,包含一个针对REST API的文件上传方法,进行文件上传。
public interface UploadResource {
@RequestLine("POST /upload-file")
@Headers("Content-Type: multipart/form-data")
Response uploadFile(@Param("file") MultipartFile file);
}
The annotation @RequestLine defines the HTTP method and the relative resource path of the API, and @Headers specifies the headers such as Content-Type.
注解@RequestLine定义了HTTP方法和API的相对资源路径,而@Headers则指定了Content-Type等标题。
Now, let’s invoke the specified method in the proxy interface. We’ll do this from our service class:
现在,让我们来调用代理接口中的指定方法。我们将从我们的服务类中做到这一点。
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;
}
Here, we have used the Feign.builder() utility to build an instance of the UploadResource proxy interface. We have also used the SpringFormEncoder and RESTful Web Service-based URL.
在这里,我们使用了Feign.builder()工具来构建UploadResource代理接口的一个实例。我们还使用了SpringFormEncoder和基于RESTful Web Service的URL。
6. Verification
6.核查
Let’s create a test to verify the file upload with the annotated client:
让我们创建一个测试来验证带注释的客户端的文件上传。
@SpringBootTest
public class OpenFeignFileUploadLiveTest {
@Autowired
private UploadService uploadService;
private static String FILE_NAME = "fileupload.txt";
@Test
public void whenAnnotatedFeignClient_thenFileUploadSuccess() {
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);
}
}
And now, let’s create another test to verify the file upload with the Feign.Builder():
现在,让我们创建另一个测试,用Feign.Builder()验证文件的上传。
@Test
public void whenFeignBuilder_thenFileUploadSuccess() throws IOException {
// same as above
Assert.assertTrue(uploadService.uploadFileWithManualClient(multipartFile));
}
7. Conclusion
7.结语
In this article, we have shown how to implement a Multipart File upload using OpenFeign, and the various ways to include it in a simple application.
在这篇文章中,我们展示了如何使用OpenFeign实现多部分文件上传,以及在一个简单的应用程序中包含它的各种方法。
We’ve also seen how to configure a Feign client or use the Feign.Builder() in order to perform the same.
我们也看到了如何配置一个Feign客户端或使用Feign.Builder()以执行同样的.。
As usual, all code samples used in this tutorial are available over on GitHub.
像往常一样,本教程中使用的所有代码样本都可以在GitHub上找到。。