1. 概要

このチュートリアルでは、OpenFeignを使用してファイルをアップロードする方法を示します。 Feign は、マイクロサービス開発者がRESTAPIを介して他のマイクロサービスと宣言的に通信するための強力なツールです。

2. 前提条件

ファイルアップロードのためにRESTfulWebサービスが公開されていると仮定しましょう。詳細は次のとおりです。

POST http://localhost:8081/upload-file

したがって、 Feign クライアントを介したファイルのアップロードを説明するために、以下に示すように、公開されたWebサービスAPIを呼び出します。

@PostMapping(value = "/upload-file")
public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
    // File upload logic
}

3. 依存関係

ファイルアップロード用のapplication/x-www-form-urlencodedおよびmultipart/form-dataエンコーディングタイプをサポートするには、 feign-core feign-が必要です。 form、および feign-form-springモジュール。

したがって、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>

内部にfeign-coreを持つspring-cloud-starter-openfeignを使用することもできます。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>3.1.0</version>
</dependency>

4. 構成

@EnableFeignClientsをメインクラスに追加しましょう。 詳細については、 spring cloud openfeignチュートリアルをご覧ください。

@SpringBootApplication
@EnableFeignClients
public class ExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}

@EnableFeignClients アノテーションを使用すると、Feignクライアントとして宣言されているインターフェイスのコンポーネントスキャンが可能になります。

5. Feignクライアントを介したファイルのアップロード

5.1. 注釈付きクライアント経由

注釈付きの@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());
            }
        }));
    }
}

FeignSupportConfig@Configuration。の注釈を付ける必要がないことに注意してください。

それでは、インターフェースを作成し、@FeignClientで注釈を付けましょう。 また、名前と構成属性を対応する値とともに追加します。

@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);
}

UploadClient は、前提条件に記載されているAPIを指します。

Hystrix を使用している間、フォールバック属性を使用して代替として追加します。 これは、アップロードAPIが失敗したときに行われます

これで、@FeignClientは次のようになります。

@FeignClient(name = "file", url = "http://localhost:8081", fallback = UploadFallback.class, configuration = FeignSupportConfig.class)

そして最後に、サービスレイヤーから直接UploadClientを呼び出すことができます。

public String uploadFile(MultipartFile file) {
    return client.fileUpload(file);
}

5.2. Feign.builder経由

場合によっては、Feign Clientをカスタマイズする必要がありますが、これは上記のような注釈の方法では不可能です。 このような場合、 Feign.builder()APIを使用してクライアントを作成します。

ファイルアップロード用のRESTAPIを対象としたファイルアップロードメソッドを含むプロキシインターフェイスを構築しましょう。

public interface UploadResource {
    @RequestLine("POST /upload-file")
    @Headers("Content-Type: multipart/form-data")
    Response uploadFile(@Param("file") MultipartFile file);
}

アノテーション@RequestLineは、HTTPメソッドとAPIの相対リソースパスを定義し、@HeadersはContent-Typeなどのヘッダーを指定します。

それでは、プロキシインターフェイスで指定されたメソッドを呼び出しましょう。 これは、サービスクラスから行います。

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;
}

ここでは、 Feign.builder()ユーティリティを使用して、UploadResourceプロキシインターフェイスのインスタンスを構築しました。 SpringFormEncoderおよびRESTfulWebサービスベースのURLも使用しました。

6. 検証

注釈付きクライアントでファイルのアップロードを検証するテストを作成しましょう。

@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);
    }
}

次に、 Feign.Builder()を使用してファイルのアップロードを検証する別のテストを作成しましょう。

@Test
public void whenFeignBuilder_thenFileUploadSuccess() throws IOException {
    // same as above
    Assert.assertTrue(uploadService.uploadFileWithManualClient(multipartFile));
}

7. 結論

この記事では、OpenFeignを使用してマルチパートファイルのアップロードを実装する方法と、それを単純なアプリケーションに含めるさまざまな方法を示しました。

また、Feignクライアントを構成する方法、または同じを実行するために Feign.Builder()を使用する方法も確認しました。

いつものように、このチュートリアルで使用されるすべてのコードサンプルはGitHubで入手できます。