Eine einfache HTTP-Anforderung in Java ausführen

Führen Sie eine einfache HTTP-Anforderung in Java durch

1. Überblick

In diesem kurzen Tutorial werden wir einway of performing HTTP requests in Java präsentieren - mithilfe der integrierten Java-KlasseHttpUrlConnection.

Weitere Lektüre:

Ein Leitfaden für HTTP-Cookies in Java

Eine schnelle und praktische Anleitung zu HTTP-Cookies in Java

Read more

Erkunden des neuen HTTP-Clients in Java 9 und 11

Entdecken Sie die neue HttpClient-API von Java 9, die viel Flexibilität und leistungsstarke Funktionen bietet.

Read more

Web- und Anwendungsserver für Java

Eine kurze Liste der verfügbaren Web- und Anwendungsserver in Java.

Read more

2. HttpUrlConnection

Die KlasseHttpUrlConnection erlaubt unsperform basic HTTP requests without the use of any additional libraries. Alle benötigten Klassen sind im Paketjava.netenthalten.

Die Nachteile dieser Methode sind, dassthe code can be more cumbersome than other HTTP libraries, and it does not provide more advanced functionalities such as dedicated methods for adding headers or authentication.

3. Anfrage erstellen

A HttpUrlConnection instance is created by using the openConnection() method of the URL class. Beachten Sie, dass diese Methode nur ein Verbindungsobjekt erstellt, die Verbindung jedoch noch nicht herstellt.

Die KlasseHttpUrlConnection wird für alle Arten von Anforderungen verwendet, indem das AttributrequestMethod auf einen der folgenden Werte gesetzt wird: GET, POST, HEAD, OPTIONEN, PUT, DELETE, TRACE.

Stellen Sie mithilfe der GET-Methode eine Verbindung zu einer bestimmten URL her:

URL url = new URL("http://example.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");

4. Anforderungsparameter hinzufügen

Wenn wir einer Anforderung Parameter hinzufügen möchten, müssen wir die EigenschaftdoOutput auftrue setzen und dannString der Formparam1=value¶m2=value inOutputStreamchreiben. s der Instanz vonHttpUrlConnection:

Map parameters = new HashMap<>();
parameters.put("param1", "val");

con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();

Um die Transformation vonparameter Map zu erleichtern, haben wir eine Dienstprogrammklasse namensParameterStringBuilder geschrieben, die eine statische MethodegetParamsString() enthält, die aMap inString vonString transformiert Erforderliches Format:

public class ParameterStringBuilder {
    public static String getParamsString(Map params)
      throws UnsupportedEncodingException{
        StringBuilder result = new StringBuilder();

        for (Map.Entry entry : params.entrySet()) {
          result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
          result.append("=");
          result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
          result.append("&");
        }

        String resultString = result.toString();
        return resultString.length() > 0
          ? resultString.substring(0, resultString.length() - 1)
          : resultString;
    }
}

5. Anforderungsheader festlegen

Das Hinzufügen von Headern zu einer Anforderung kann mithilfe dersetRequestProperty()-Methode erreicht werden:

con.setRequestProperty("Content-Type", "application/json");

Um den Wert eines Headers aus einer Verbindung zu lesen, können Sie die MethodegetHeaderField()verwenden:

String contentType = con.getHeaderField("Content-Type");

6. Zeitüberschreitungen konfigurieren

HttpUrlConnection Klasse erlaubtsetting the connect and read timeouts. Diese Werte legen fest, wie lange gewartet werden soll, bis die Verbindung zum Server hergestellt ist oder Daten zum Lesen verfügbar sind.

Um die Timeout-Werte festzulegen, können Sie die MethodensetConnectTimeout() undsetReadTimeout() verwenden:

con.setConnectTimeout(5000);
con.setReadTimeout(5000);

Im obigen Beispiel haben wir beide Timeout-Werte auf 5 Sekunden eingestellt.

7. Umgang mit Cookies

Dasjava.net-Paket enthält Klassen, die das Arbeiten mit Cookies wieCookieManager undHttpCookie erleichtern.

Zunächst können wir zuread the cookies from a response den Wert des HeadersSet-Cookie abrufen und ihn in eine Liste der Objekte vonHttpCookieanalysieren:

String cookiesHeader = con.getHeaderField("Set-Cookie");
List cookies = HttpCookie.parse(cookiesHeader);

Als nächstes werden wiradd the cookies to the cookie store:

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));

Überprüfen wir, ob ein Cookie mit dem Namenusername vorhanden ist. Wenn nicht, fügen wir es dem Cookie-Speicher mit dem Wert "john" hinzu:

Optional usernameCookie = cookies.stream()
  .findAny().filter(cookie -> cookie.getName().equals("username"));
if (usernameCookie == null) {
    cookieManager.getCookieStore().add(null, new HttpCookie("username", "john"));
}

Schließlich müssen wir nach dem Schließen und erneuten Öffnen der Verbindung denCookie-Header aufadd the cookies to the request setzen:

con.disconnect();
con = (HttpURLConnection) url.openConnection();

con.setRequestProperty("Cookie",
  StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

8. Weiterleitungen bearbeiten

Wir könnenenable or disable automatically following redirects for a specific connection verwenden, indem wir diesetInstanceFollowRedirects()-Methode mit dem Parametertrue oderfalse verwenden:

con.setInstanceFollowRedirects(false);

Es ist auch möglich,enable or disable automatic redirect for all connections:

HttpUrlConnection.setFollowRedirects(false);

Standardmäßig ist das Verhalten aktiviert.

Wenn eine Anfrage einen Statuscode 301 oder 302 zurückgibt, der eine Umleitung anzeigt, können wir den Header vonLocationabrufen und eine neue Anfrage an die neue URL erstellen:

if (status == HttpURLConnection.HTTP_MOVED_TEMP
  || status == HttpURLConnection.HTTP_MOVED_PERM) {
    String location = con.getHeaderField("Location");
    URL newUrl = new URL(location);
    con = (HttpURLConnection) newUrl.openConnection();
}

9. Antwort lesen

Das Lesen der Antwort der Anforderung kann durchparsing the InputStream of the HttpUrlConnection instance erfolgen.

Um die Anforderung auszuführen, können wir die MethodengetResponseCode(), connect(), getInputStream() odergetOutputStream() verwenden:

int status = con.getResponseCode();

Lesen Sie abschließend die Antwort der Anfrage und platzieren Sie sie in einemcontent String:

BufferedReader in = new BufferedReader(
  new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
}
in.close();

Fürclose the connection können wir diedisconnect()-Methode verwenden:

con.disconnect();

10. Lesen der Antwort auf fehlgeschlagene Anforderungen

Wenn die Anforderung fehlschlägt, funktioniert der Versuch, dieInputStream derHttpUrlConnection-Instanz zu lesen, nicht. Stattdessenwe can consume the stream provided by HttpUrlConnection.getErrorStream().

Wir können entscheiden, welcheInputStream verwendet werden sollen, indem wir den HTTP-Statuscode vergleichen:

int status = con.getResponseCode();

Reader streamReader = null;

if (status > 299) {
    streamReader = new InputStreamReader(con.getErrorStream());
} else {
    streamReader = new InputStreamReader(con.getInputStream());
}

Und schließlich können wir diestreamReader auf die gleiche Weise wie im vorherigen Abschnitt lesen.

11. Erstellen der vollständigen Antwort

Es ist nicht möglich, die vollständige Antwortdarstellung mit derHttpUrlConnection -Sinstanz zu erhalten.

we can build it using some of the methods that the HttpUrlConnection instance offers:

public class FullResponseBuilder {
    public static String getFullResponse(HttpURLConnection con) throws IOException {
        StringBuilder fullResponseBuilder = new StringBuilder();

        // read status and message

        // read headers

        // read response content

        return fullResponseBuilder.toString();
    }
}

Hier lesen wir die Teile der Antworten, einschließlich des Statuscodes, der Statusmeldung und der Header, und fügen diese einerStringBuilder-Instanz hinzu.

Fügen wir zunächst die Antwortstatusinformationen hinzu:

fullResponseBuilder.append(con.getResponseCode())
  .append(" ")
  .append(con.getResponseMessage())
  .append("\n");

Next, we’ll get the headers using getHeaderFields()and fügt jeden von ihnen zu unserenStringBuilder im Format HeaderName:HeaderValues: hinzu

con.getHeaderFields().entrySet().stream()
  .filter(entry -> entry.getKey() != null)
  .forEach(entry -> {
      fullResponseBuilder.append(entry.getKey()).append(": ");
      List headerValues = entry.getValue();
      Iterator it = headerValues.iterator();
      if (it.hasNext()) {
          fullResponseBuilder.append(it.next());
          while (it.hasNext()) {
              fullResponseBuilder.append(", ").append(it.next());
          }
      }
      fullResponseBuilder.append("\n");
});

Finally, we’ll read the response content wie zuvor und hängen es an.

Beachten Sie, dass diegetFullResponse -Smethod überprüft, ob die Anforderung erfolgreich war oder nicht, um zu entscheiden, obcon.getInputStream() odercon.getErrorStream() zum Abrufen des Inhalts der Anforderung verwendet werden müssen.

12. Fazit

In diesem Artikel haben wir gezeigt, wie wir HTTP-Anforderungen mit der KlasseHttpUrlConnectionausführen können. Der vollständige Quellcode der Beispiele istover on GitHub.