[JAVA] Mehrteilige Anforderungsantwort von HttpURLConnection (und Apache Commons)

Ein bestimmter Server empfängt eine mehrteilige Anfrage und gibt eine mehrteilige Antwort zurück, also ein Memo der entsprechenden Implementierung

Umgebung

Implementierung

Unterrichtsvorbereitung

Erstellen Sie eine Klasse, die den UploadContext von commons-fileupload implementiert, um die mehrteilige Antwort zu verarbeiten (obwohl es sich seltsam anfühlt, die Antwort zu erhalten). Definieren Sie außerdem den InputStream, der die Antwort für die Methodenimplementierung von UploadContext als Mitglied erhält. Da die Antwort diesmal prüft, ob die Antwort mehrteilig oder der Header ist, ist HttpURLConnection auch Mitglied. Implementieren Sie außerdem die UploadContext-Methode, die zum Verarbeiten des Multiparts erforderlich ist.

Klassendefinition


public class MultipartRequestResponse implements UploadContext {

    private InputStream is;
    private HttpURLConnection connection;

    //Implementieren Sie mindestens den Inhalt von getInputStream
    @Override
    public InputStream getInputStream() throws IOException {
        return is;
    }

    //Implementieren Sie sie gegebenenfalls zur Überprüfung des Antwortheaders
    @Override
    public String getContentType() {
        return connection.getHeaderField("Content-Type");
    }

    //Andere Methoden, die Override erfordern, sind vorerst nur implementiert und werden daher weggelassen.
    //・ ・ ・
}

Anfrage

Vorbereitung

Erstellen Sie eine Grenze für das Teil

Da die Grenze wiederholt verwendet wird, ist es einfacher, sie zuerst als Klassenvariable zu erstellen. Da dies ein Test ist, ist er behoben, aber ich denke, es ist besser, eine zufällige Ausgabe zu ermöglichen, unter Berücksichtigung der Grenzspezifikationen und der Untersuchung, wenn etwas passiert.

Definieren Sie die Grenze mit einer Klassenvariablen


private static final String BOUNDARY = "--boundary";
Einstellungen anfordern

Bereiten Sie die URL des Anforderungsziels und den Anforderungsheader vor. Der Anforderungsheader wird gemäß den Spezifikationen des Servers festgelegt.

URL url = new URL("https://hogehoge");

connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
connection.setRequestProperty("host", url.getHost());
//Wenn es andere notwendige Einstellungen gibt

Anfrage senden

Stellen Sie das Multipart im Anforderungshauptteil ein

Rufen Sie den OutputStream von der HttpURLConnection-Instanz ab und schreiben Sie den Body.

Der Körper muss auch Zeilenumbrüche und Grenzen gemäß den mehrteiligen Spezifikationen schreiben. Der Zeilenumbruch muss übrigens CRLF sein (ich habe ihn einmal mit LF gesendet und konnte mit dem Multipart nicht gut umgehen).

Definieren Sie den Zeilenvorschubcode mit einer Klassenvariablen


private static final String CRLF = "\r\n";

Anfrage senden


//Starten Sie die Kommunikation mit dem Server
OutputStream os = connection.getOutputStream();

StringBuilder multipartBody = new StringBuilder();
multipartBody.append(CRLF);
//Teil(JSON)
multipartBody.append(BOUNDARY).append(CRLF);
multipartBody.append("Content-Disposition: form-data; name=\"parameter1\"").append(CRLF);
multipartBody.append("Content-Type: application/json; charset=utf-8").append(CRLF);
multipartBody.append("Content-Transfer-Encoding: 8bit").append(CRLF);
multipartBody.append(CRLF);
multipartBody.append("{\"hoge\": \"fuga\"}" + CRLF);
//Endteil
multipartBody.append(BOUNDARY).append("--");

//Schreiben Sie den Text in OutputStream
os.write(multipartBody.toString().getBytes());
//Body an Server senden
os.close();

Durch Aufrufen von HttpURLConnection # getOutputStream () wird die Kommunikation mit dem Server gestartet und der Header gesendet. Durch Aufrufen von OutputStream # close () wird der schriftliche Anforderungshauptteil an den Server gesendet. Wenn Sie OutputStream # flush () für jedes Teil aufrufen, können Sie den Text jedes Mal zum Server fliegen, aber er wurde nicht gesendet. Ich möchte diesen Bereich separat überprüfen und erneut einen Artikel schreiben.

Antwort

Es ist ein Prozess, bei dem die Serverseite die Antwort in mehreren Teilen zurückgibt. Ich bin jedoch der Meinung, dass es möglicherweise nicht möglich ist, den InputStream der Antwort zu analysieren, aber ich werde ihn mithilfe von Apache Commons verarbeiten.

//Antwort erhalten
is = connection.getInputStream();

//Überprüfen Sie, ob die Antwort mehrteilig ist
// getContentType()Der Rückgabewert von wird geprüft
if (!FileUpload.isMultipartContent((RequestContext) this)) {
    //Was tun, wenn die Antwort nicht mehrteilig ist?
}

//Konvertiert den Inhalt von InputStream in Iterator
FileUpload upload = new FileUpload();
FileItemIterator fit = upload.getItemIterator(this);

//Schleife für jeden Teil des Antwortkörpers
while (fit.hasNext()) {
    FileItemStream fis = fit.next();
    //Feldnamen des Teils abrufen
    String field = fis.getFieldName();
    //Holen Sie sich InputStream des Teils
    InputStream isPart = fis.openStream();

    //Danach ist es in Ordnung, wenn Sie den Inhalt des Teils verarbeiten
    //・ ・ ・
}

Wenn Sie mit FileItemIterator eine Antwort erhalten, können Sie diese in einer Schleife drehen und die Teile einzeln verarbeiten.

Ich werde den Beispielcode bereinigen und später auf github veröffentlichen.

Recommended Posts

Mehrteilige Anforderungsantwort von HttpURLConnection (und Apache Commons)
Anforderungs- und Antwortprotokolle mit Spring Boot ausgeben
Apache und Tomcat
Suche nach POST-Anforderung mit Azure Search + Java Apache HttpClient