Перейти к основному содержимому

Загрузка файла с помощью Open Feign

· 4 мин. чтения

1. Обзор

В этом уроке мы покажем, как загрузить файл с помощью Open Feign. Feign — это мощный инструмент, с помощью которого разработчики микросервисов могут декларативно взаимодействовать через REST API с другими микросервисами.

2. Обязательное условие

Предположим, что веб-служба RESTful открыта для загрузки файла, и ниже приведены подробности:

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

Итак, чтобы объяснить загрузку файла через клиент Feign , мы будем вызывать открытый 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>

Мы также можем использовать 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. Конфигурация

Давайте добавим @EnableFeignClients в наш основной класс. Вы можете посетить учебное пособие по открытию весеннего облака для получения более подробной информации:

@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 Clients необходимо настраивать, что невозможно с помощью аннотации, как описано выше. В таком случае мы создаем клиентов с помощью API Feign.builder() .

Давайте создадим прокси-интерфейс, содержащий метод загрузки файла, ориентированный на REST API для загрузки файла:

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 и URL-адрес на основе веб-службы RESTful.

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.