[JAVA] Comment réaliser le téléchargement de fichiers avec Feign

1.Tout d'abord

Dernière fois a expliqué comment réaliser le téléchargement de fichiers avec Feign. Cette fois, je voudrais expliquer comment réaliser le téléchargement de fichiers avec Feign. J'ai implémenté mon propre Decoder dans le téléchargement, mais je vais l'utiliser car il existe un module dédié appelé feign-form pour le téléchargement. .. La page officielle de GitHub explique ce qui suit.

This module adds support for encoding application/x-www-form-urlencoded and multipart/form-data forms.

2. Préparation de la bibliothèque

feign-form est un module séparé, alors ajoutez-le à la dépendance. Pour le pom.xml de base lors de l'utilisation de Feign, reportez-vous à Un autre article.

pom.xml


    <!-- add feign-form for multipart : start -->
    <dependency>
        <groupId>io.github.openfeign.form</groupId>
        <artifactId>feign-form</artifactId>
        <version>3.3.0</version>
    </dependency>
    <!-- add feign-form for multipart : end -->

3. Définition de l'interface API

Définit l'interface API. Les trois types de types de données d'argument suivants peuvent être utilisés pour la conversion de données de téléchargement de fichiers (sérialisation).

À titre d'exemple, j'aimerais utiliser trois types de données cette fois.

UploadApi.java


package com.example.feign.demo.upload;

import java.io.File;

import feign.Headers;
import feign.Param;
import feign.RequestLine;
import feign.form.FormData;

public interface UploadApi {

    @RequestLine("POST /data/upload")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("remarks") String remarks, @Param("uploadFile") File uploadFile);

    @RequestLine("POST /data/upload")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("remarks") String remarks, @Param("uploadFile") byte[] uploadFile);

    @RequestLine("POST /data/upload")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("remarks") String remarks, @Param("uploadFile") FormData uploadFile);
}

** Veuillez noter que les trois types ne fonctionnent pas de la même manière. Vérifiez les spécifications du côté du fournisseur d'API (serveur) et utilisez celle qui convient. ** **

Type de données Content-Disposition:FileMaker Content-Type:
java.io.File ○: Définir ◯: Set (jugement automatique depuis l'extension)
byte[] ×: non défini ×: non défini
Uniformeapplication/octet-streamDevient
feign.form.FormData ×: non défini ○: Set (défini explicitement par le programme)

4. Comment utiliser

Le but est de définir une instance de la classe feign.form.FormEncoder dans la méthode ʻencoder`. D'autres sont identiques à l'utilisation de base de «Feign».

DownloadDemo.java


package com.example.feign.demo.upload;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import feign.Feign;
import feign.Logger;
import feign.form.FormData;
import feign.form.FormEncoder;
import feign.jackson.JacksonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;

public class UploadDemo {

    public static void main(String[] args) {
        // 1. create instance of api interface with feign
        UploadApi uploadApi = Feign.builder()
                .client(new OkHttpClient())
                // use FormEncoder with JacksonEncoder
                .encoder(new FormEncoder(new JacksonEncoder()))
                // .encoder(new FormEncoder())
                .logger(new Slf4jLogger())
                .logLevel(Logger.Level.FULL)
                .target(UploadApi.class, "http://localhost:3000");

        // 2. call api
        // File
        File uploadFile = new File("C:/tmp/test.png ");
        String remarks = "I send a image file.";
        String result = uploadApi.upload(remarks, uploadFile);
        System.out.println(result);

        try (FileInputStream iStream = new FileInputStream(uploadFile);) {
            // byte[]
            byte[] uploadFileByte = new byte[(int) uploadFile.length()];
            iStream.read(uploadFileByte);
            String result2 = uploadApi.upload(remarks, uploadFileByte);
            System.out.println(result2);
            // FormData
            FormData formData = new FormData("image/png", uploadFileByte);
            String result3 = uploadApi.upload(remarks, formData);
            System.out.println(result3);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5. Expliquez la différence entre les trois types avec le code d'implémentation (bonus)

Le code d'implémentation de feign-form est ouvert au public, vous pouvez donc voir la différence entre les trois types d'opérations. «FormData» peut être résolu en lui donnant un champ «filename», mais la raison pour laquelle il n'est pas conservé est un mystère. (Bien qu'il conserve contentType)

5.1. File

https://github.com/OpenFeign/feign-form/blob/master/feign-form/src/main/java/feign/form/multipart/SingleFileWriter.java

SingleFileWriter.Où la méthode writeFileMetadata de la classe parente (AbstractWriter) est appelée en java


writeFileMetadata(output, key, file.getName(), null);

https://github.com/OpenFeign/feign-form/blob/master/feign-form/src/main/java/feign/form/multipart/AbstractWriter.java

AbstractWriter.Méthode java writeFileMetadata


  @SneakyThrows
  protected void writeFileMetadata (Output output, String name, String fileName, String contentType) {
    val contentDesposition = new StringBuilder()
        .append("Content-Disposition: form-data; name=\"").append(name).append("\"; ")
        .append("filename=\"").append(fileName).append("\"")
        .toString();

    String fileContentType = contentType;
    if (fileContentType == null) {
      if (fileName != null) {
        fileContentType = URLConnection.guessContentTypeFromName(fileName);
      }
      if (fileContentType == null) {
        fileContentType = "application/octet-stream";
      }
    }

    val string = new StringBuilder()
        .append(contentDesposition).append(CRLF)
        .append("Content-Type: ").append(fileContentType).append(CRLF)
        .append("Content-Transfer-Encoding: binary").append(CRLF)
        .append(CRLF)
        .toString();

    output.write(string);
  }

En d'autres termes, dans le cas de "Fichier", ce sera comme suit.

5.2. byte[]

https://github.com/OpenFeign/feign-form/blob/master/feign-form/src/main/java/feign/form/multipart/ByteArrayWriter.java

ByteArrayWriter.Où la méthode writeFileMetadata de la classe parente (AbstractWriter) est appelée en java


writeFileMetadata(output, key, null, null);

En d'autres termes, dans le cas de byte [], ce sera comme suit.

5.3. FormData

https://github.com/OpenFeign/feign-form/blob/master/feign-form/src/main/java/feign/form/multipart/FormDataWriter.java

FormDataWriter.Où la méthode writeFileMetadata de la classe parente (AbstractWriter) est appelée en java


writeFileMetadata(output, key, null, formData.getContentType());

En d'autres termes, dans le cas de «FormData», ce sera comme suit.

6. Enfin

Cette fois, j'ai expliqué comment réaliser le téléchargement de fichiers avec Feign. Je pense que c'était plus facile que de télécharger à cause des modules fournis.

Recommended Posts

Comment réaliser le téléchargement de fichiers avec Feign
Comment réaliser le téléchargement de fichiers avec Feign
Comment réaliser un téléchargement de fichiers volumineux avec TERASOLUNA 5.x (= Spring MVC)
Comment réaliser un téléchargement de fichiers volumineux avec Rest Template of Spring
J'ai essayé d'implémenter le téléchargement de fichiers avec Spring MVC
Comment numéroter (nombre) avec html.erb
Comment mettre à jour avec activerecord-import
Comment tester l'écran de téléchargement de fichiers avec Spring + Selenium
Comment demander un fichier CSV au format JSON avec jMeter
Comment inverser la compilation du fichier apk en code source Java avec MAC
Comment configurer un proxy avec authentification dans Feign
Comment démarrer avec Slim
Comment entourer n'importe quel caractère avec "~"
Comment convertir un fichier erb en haml
Comment atteindre le rang D de Paiza
[Débutant] Comment supprimer AUCUN FICHIER
Comment démarrer Camunda avec Docker
Comment créer un fichier jar sans dépendances dans Maven
Comment charger un fichier de téléchargement Spring et afficher son contenu
Téléchargement automatique de fichiers avec l'ancienne gemme Ruby Que faire avec Watir
Comment gérer l'événement où Committee :: InvalidRequest se produit en comité pendant le test de téléchargement de fichier Rspec
Comment recadrer une image avec libGDX
Comment ajuster TextPosition avec l'extension de clavier iOS
[Java] Comment utiliser la classe File
Comment compiler Java avec VsCode & Ant
[Rails] Comment télécharger des images à l'aide de Carrierwave
[Java] Résumez comment comparer avec la méthode equals
[Android] Comment gérer les thèmes sombres
Comment utiliser BootStrap avec Play Framework
[Note] Comment démarrer avec Rspec
Télécharger le fichier image de l'application Rails sur S3
Comment ajouter un fichier jar dans ScalaIDE
Comment faire un contrôle basé sur l'API avec cancancan
Comment implémenter TextInputLayout avec la fonction de validation
Comment gérer les erreurs de connexion avec l'appareil
Comment supprimer des données avec une clé externe
Comment tester l'étendue privée avec JUnit
Comment surveiller nginx avec docker-compose avec datadog
Comment diviser un fichier de message Spring Boot
Comment exécuter Blazor (C #) avec Docker
Comment créer un environnement Rails 6 avec Docker
Comment démarrer un conteneur Docker avec un volume monté dans un fichier de commandes
Comment télécharger Oracle JDK 8 rpm avec curl
[Java] Comment tester s'il est nul dans JUnit
Comment se moquer de chaque cas avec Mockito 1x
[Rails] Comment lire le fichier XML téléchargé depuis l'écran en type Hash
[Ruby] Comment convertir un fichier CSV en Yaml (Yml)
Comment se moquer de chaque cas avec PowerMock + Mockito1x
Comment tester les interruptions pendant Thread.sleep avec JUnit
Envoyez et traitez les données de formulaire au servlet avec l'objet FormData et le téléchargement de fichier Commons
Comment vider de la base de données (DB) vers le fichier de départ
Comment utiliser h2db intégré avec Spring Boot