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.