[JAVA] So erreichen Sie das Hochladen von Dateien mit Feign

1. Zuallererst

Letztes Mal erklärte, wie man mit Feign einen Dateidownload erreicht. Dieses Mal möchte ich erklären, wie man das Hochladen von Dateien mit Feign realisiert. Ich habe meinen eigenen "Decoder" im Download implementiert, aber ich werde diesen verwenden, da es ein dediziertes Modul namens feign-form zum Hochladen gibt. .. Die offizielle Seite von GitHub erklärt Folgendes.

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

2. Vorbereitung der Bibliothek

feign-form ist ein separates Modul, also füge es der Abhängigkeit hinzu. Informationen zur grundlegenden pom.xml bei Verwendung von Feign finden Sie unter Ein anderer Artikel.

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. Definition der API-Schnittstelle

Definiert die API-Schnittstelle. Es gibt die folgenden drei Arten von Argumentdatentypen, die für die Konvertierung von Datei-Upload-Daten (Serialisierung) verwendet werden können.

Als Beispiel möchte ich diesmal drei Arten von Daten verwenden.

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

** Bitte beachten Sie, dass nicht alle drei Typen gleich funktionieren. Überprüfen Sie die Spezifikationen auf der Seite des API-Anbieters (Servers) und verwenden Sie die entsprechende. ** ** **

Datentyp Content-Disposition:FileMaker Content-Type:
java.io.File ○: Einstellen ◯: Set (automatische Beurteilung durch Verlängerung)
byte[] ×: Nicht eingestellt ×: Nicht eingestellt
Uniformapplication/octet-streamWird
feign.form.FormData ×: Nicht eingestellt ○: Set (explizit vom Programm gesetzt)

4. Verwendung

Es geht darum, eine Instanz der Klasse "feign.form.FormEncoder" in der Methode "encoder" festzulegen. Andere sind die gleichen wie die Grundverwendung von "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. Erläutern Sie den Unterschied zwischen den drei Typen mit dem Implementierungscode (Bonus).

Der Implementierungscode von feign-form ist öffentlich zugänglich, sodass Sie den Unterschied zwischen den drei Arten von Vorgängen erkennen können. FormData kann gelöst werden, indem man ihm ein Feld mit Dateiname gibt, aber es ist ein Rätsel, warum es nicht beibehalten wird. (Obwohl es "contentType" behält)

5.1. File

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

SingleFileWriter.Wobei die writeFileMetadata-Methode der übergeordneten Klasse (AbstractWriter) in Java aufgerufen wird


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.Java WriteFileMetadata-Methode


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

Mit anderen Worten, im Fall von "Datei" ist dies wie folgt.

5.2. byte[]

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

ByteArrayWriter.Wobei die writeFileMetadata-Methode der übergeordneten Klasse (AbstractWriter) in Java aufgerufen wird


writeFileMetadata(output, key, null, null);

Mit anderen Worten, im Fall von "byte []" ist es wie folgt.

5.3. FormData

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

FormDataWriter.Wobei die writeFileMetadata-Methode der übergeordneten Klasse (AbstractWriter) in Java aufgerufen wird


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

Mit anderen Worten, im Fall von "FormData" ist dies wie folgt.

6. Schließlich

Dieses Mal erklärte ich, wie man das Hochladen von Dateien mit "Feign" realisiert. Ich denke, es war einfacher als das Herunterladen aufgrund der bereitgestellten Module.

Recommended Posts

So erreichen Sie das Hochladen von Dateien mit Feign
So erreichen Sie den Dateidownload mit Feign
So realisieren Sie mit TERASOLUNA 5.x (= Spring MVC) das Hochladen großer Dateien
So erzielen Sie mit Rest Template of Spring einen großen Datei-Upload
Ich habe versucht, das Hochladen von Dateien mit Spring MVC zu implementieren
Wie man mit html.erb nummeriert (nummeriert)
So aktualisieren Sie mit activerecord-import
So testen Sie den Bildschirm zum Hochladen von Dateien mit Spring + Selenium
So fordern Sie mit jMeter eine CSV-Datei als JSON an
So kehren Sie die Kompilierung der Apk-Datei in Java-Quellcode mit MAC um
So richten Sie einen Proxy mit Authentifizierung in Feign ein
Wie fange ich mit schlank an?
Wie man ein Zeichen mit "~" einschließt
So konvertieren Sie erb-Datei in haml
Wie man Paiza Rang D erreicht
[Anfänger] So löschen Sie NO FILE
So starten Sie Camunda mit Docker
So erstellen Sie eine JAR-Datei ohne Abhängigkeiten in Maven
So laden Sie eine Spring-Upload-Datei und zeigen ihren Inhalt an
Automatischer Datei-Upload mit altem Ruby-Edelstein Was tun mit Watir?
Umgang mit dem Ereignis, dass Committee :: InvalidRequest während des Rspec-Datei-Upload-Tests im Committee auftritt
So beschneiden Sie ein Bild in libGDX
So passen Sie TextPosition mit der iOS-Tastaturerweiterung an
[Java] Verwendung der File-Klasse
So kompilieren Sie Java mit VsCode & Ant
[Rails] So laden Sie Bilder mit Carrierwave hoch
[Java] Fassen Sie zusammen, wie Sie mit der Methode equals vergleichen können
[Android] Wie man mit dunklen Themen umgeht
Verwendung von BootStrap mit Play Framework
[Hinweis] Erste Schritte mit Rspec
Laden Sie die Rails-App-Image-Datei in S3 hoch
So fügen Sie eine JAR-Datei in ScalaIDE hinzu
API-basierte Steuerung mit cancancan
So implementieren Sie TextInputLayout mit Validierungsfunktion
So behandeln Sie Anmeldefehler mit devise
So löschen Sie Daten mit einem externen Schlüssel
So testen Sie den privaten Bereich mit JUnit
So überwachen Sie Nginx mit Docker-Compose mit Datadog
So teilen Sie eine Spring Boot-Nachrichtendatei
So führen Sie Blazor (C #) mit Docker aus
So erstellen Sie eine Rails 6-Umgebung mit Docker
So starten Sie einen Docker-Container mit einem in einer Batchdatei bereitgestellten Volume
So laden Sie Oracle JDK 8 U / min mit Curl herunter
[Java] So testen Sie, ob es in JUnit null ist
Wie man jeden Fall mit Mockito 1x verspottet
[Rails] Lesen der vom Bildschirm hochgeladenen XML-Datei im Hash-Typ
[Ruby] So konvertieren Sie eine CSV-Datei in Yaml (Yml)
Wie man jeden Fall mit PowerMock + Mockito1x verspottet
So testen Sie Interrupts während Thread.sleep mit JUnit
Senden und verarbeiten Sie Formulardaten mit FormData-Objekt und Commons File Upload an Servlet
So sichern Sie von der Datenbank (DB) in die Seeds-Datei
Verwendung des eingebauten h2db mit Federstiefel