Features HttpUrlConnection von java.net

Guten Tag,

Heute werde ich versuchen, darüber zu sprechen, wie Sie eine Anfrage senden und die Antwort vom HTTP-Server mithilfe der URLConnection aus der JRE-Bibliothek lesen können.

Wir lernen derzeit Java online. Unser gesamtes Team nutzt Slack für Arbeit und Kommunikation. Für Informationen zu Benutzern verwenden wir die Slack-API. Um nicht lange über die API selbst zu sprechen (dies ist ein Thema für einen separaten Artikel), möchte ich kurz sagen: Die Slack-API basiert auf dem HTTP-Protokoll. Um Informationen über Benutzer zu erhalten, müssen Sie eine Anforderung mit einem URI senden, in dem ein Methodenname von der API an die API der Hostadresse vorhanden sein muss . slack.com Hier ist eine Liste einiger Methoden:
  • users.list
  • chat.postMessage
  • Gespräche.erstellen
  • files.upload
  • im.open

Um eine Benutzerliste zu erhalten, benötigen Sie die Methode users.list. Wir bilden die URI - /api/users.list im Anfragetext. In der Formularanwendung / x-www-form-urlencoded sollte sich ein Authentifizierungstoken befinden. Das heißt, die Anfrage sollte ungefähr so ​​aussehen (aber es gibt eine Nuance, die niedriger sein wird):

GET /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5 


Ich wusste von der Apache HttpComponents-Bibliothek, aber zu Forschungszwecken werden wir die in der Standard-Java 8-Bibliothek verfügbaren Tools verwenden, nämlich die Implementierung von java.net.URLConnection.

Um die URLConnection-Entität zu erhalten, müssen Sie das Objekt der Klasse java.net.URL verwenden. Der Konstruktor verwendet den Typ String, in dem zusätzlich zu allem das Protokoll angegeben werden muss - in unserem Fall https.

Nach dem Empfang der URL-Entität rufen wir die openConnection () -Methode auf, die die HttpsUrlConnection-Entität zurückgibt.

 String url = “https://slack.com/api/users.list”; URLConnection connection = new URL(url).openConnection(); 

In diesem Fall müssen Sie MalformedUrlException und IOException behandeln oder auslösen.

Danach speichert die Verbindungsvariable einen Verweis auf das HttpsUrlConnectionImpl-Objekt. Standardmäßig wird eine GET-Anforderung generiert. Um einen Header hinzuzufügen, verwenden wir die Methode setRequestProperty () , die Schlüssel und Wert akzeptiert. Wir müssen hier einen Inhaltstyp installieren, der den Wert application / x-www-form-urlencoded hat . Nun, und wir machen es!
 connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded”); 

Jetzt muss nur noch eine Anfrage gesendet werden, indem unser Token geschrieben und in den Körper begrenzt wird. Setzen Sie dazu das Feld doOutput des Verbindungsobjekts mit der Methode setDoOutput () auf true.

 connection.setDoOutput(true); 

Als nächstes der interessanteste Teil - Sie müssen unseren Anfragetext irgendwie an einen OutputStream übergeben. Wir werden OutputStreamWriter verwenden:

 OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); 

Es gibt eine Einschränkung: Nachdem wir die Methode getOutputStream () aufgerufen haben, ändert sich die Anforderungsmethode in POST, da GET den Anforderungshauptteil nicht bereitstellt. Der Vorteil besteht jedoch darin, dass Slack die Methode nicht streng einschränkt, sodass alles in Ordnung war. Und so sollte die GET-Anfrage folgendermaßen aussehen:
 GET /users.list?token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100 HTTP/1.1 Content-Type: application/x-www-form-urlencoded 

Aber ich fing nicht an, es zu wiederholen. Und stattdessen stellte sich unsere Anfrage wie folgt heraus:

 POST /users.list HTTP/1.1 Content-Type: application/x-www-form-urlencoded token=xoxp-1234567890-098765-4321-a1b2c3d4e5 

(* Einige Header werden von HttpsUrlConnection selbst gesetzt und fehlen hier.)

Um unseren Anfragetext zu schreiben, verwenden wir write ();
 String reqBody = “token=xoxp-1234567890-098765-4321-a1b2c3d4e5&limit=100”; writer.write(reqBody); writer.close(); 

Danach wird unsere Anfrage gesendet und wir können die empfangene Antwort lesen. Es ist wichtig, OutputStream zu schließen oder flush () auszuführen, bevor ein InputStream empfangen wird, da sonst die Daten den Puffer nicht verlassen (alternativ können Sie PrintStream verwenden - in der println () -Methode wird flush () standardmäßig aufgerufen). Zum Lesen habe ich BufferedReader verwendet:
 StringBuilder respBody = new StringBuilder(); BufferedReader reader = new BufferedReader(connection.getInputStream()); reader.lines().forEach(l -> respBody.append(l + “\r\n”); reader.close(); 

(* benutze lines (), um Stream bei der Ausgabe zu erhalten; \ r \ n - CRLF-Zeichen - fügt einen Übergang zu einer neuen Zeile ein)

Wenn wir uns erfolgreich authentifizieren, sollte die Variable respBody unsere Antwort vom Server speichern, der in unserem Fall ein JSON-Objekt ist. Danach kann es zur nächsten Verarbeitungsstufe gesendet werden.

Nach einigen Optimierungen sieht alles so aus:

 package main.java.com.bilichenko.learning; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.Optional; import java.util.stream.Collectors; public class SlackClient { private static final String HOST = "https://api.slack.com"; private static final String GET_USERS_URI = "/api/users.list"; private static final String TOKEN = "xx-ooo-YOUR-TOKEN-HERE"; public static void main(String[] args) throws IOException { SlackClient slackClient = new SlackClient(); System.out.println(slackClient.getRawResponse(HOST + GET_USERS_URI, "application/x-www-form-urlencoded", "token=" + TOKEN).orElse("no response")); } public Optional<String> getRawResponse(String url, String contentType, String requestBody) throws MalformedURLException, IOException { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("Content-Type", contentType); connection.setConnectTimeout(10000); connection.setRequestMethod("POST"); connection.setDoOutput(true); try(OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { writer.write(requestBody); } if (connection.getResponseCode() != 200) { System.err.println("connection failed"); return Optional.empty(); } try(BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream(), Charset.forName("utf-8")))) { return Optional.of(reader.lines().collect(Collectors.joining(System.lineSeparator()))); } } } 

Hoffe es war hilfreich!

Source: https://habr.com/ru/post/de459080/


All Articles