URLs mit HttpClient kürzen

1. Übersicht

In diesem Artikel wird gezeigt, wie URLs mit HttpClient gekürzt werden .

Ein einfaches Beispiel ist , wenn die Original - URL hat einmal verkürzt worden - durch einen Dienst wie bit.ly .

Ein komplexeres Beispiel ist, wenn die URL durch verschiedene solche Dienste mehrfach gekürzt wurde und mehrere Durchgänge erforderlich sind, um zur ursprünglichen vollständigen URL zu gelangen.

Wenn Sie tiefer graben und andere coole Dinge lernen möchten, die Sie mit dem HttpClient tun können, gehen Sie zum Haupt-HttpClient-Tutorial .

2. Kürzen Sie die URL einmal

Fangen wir einfach an: Entkürzen Sie eine URL, die nur einmal über einen verkürzten URL-Dienst übergeben wurde.

Als erstes benötigen wir einen http-Client, der Weiterleitungen nicht automatisch folgt :

CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();

Dies ist erforderlich, da wir die Umleitungsantwort manuell abfangen und Informationen daraus extrahieren müssen.

Wir beginnen mit dem Senden einer Anfrage an die verkürzte URL - die Antwort, die wir zurückerhalten, ist 301 Permanent verschoben .

Dann müssen wir den Location- Header extrahieren, der auf den nächsten zeigt, und in diesem Fall die endgültige URL:

public String expandSingleLevel(String url) throws IOException { HttpHead request = null; try { request = new HttpHead(url); HttpResponse httpResponse = client.execute(request); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode != 301 && statusCode != 302) { return url; } Header[] headers = httpResponse.getHeaders(HttpHeaders.LOCATION); Preconditions.checkState(headers.length == 1); String newUrl = headers[0].getValue(); return newUrl; } catch (IllegalArgumentException uriEx) { return url; } finally { if (request != null) { request.releaseConnection(); } } }

Zum Schluss ein einfacher Live-Test zum Erweitern einer URL:

@Test public void givenShortenedOnce_whenUrlIsUnshortened_thenCorrectResult() throws IOException { String expectedResult = "/rest-versioning"; String actualResult = expandSingleLevel("//bit.ly/13jEoS1"); assertThat(actualResult, equalTo(expectedResult)); }

3. Verarbeiten Sie mehrere URL-Ebenen

Das Problem bei kurzen URLs besteht darin, dass sie durch insgesamt unterschiedliche Dienste mehrfach verkürzt werden können. Das Erweitern einer solchen URL erfordert mehrere Durchgänge, um zur ursprünglichen URL zu gelangen.

Wir werden die zuvor definierte primitive Operation expandSingleLevel anwenden, um einfach die gesamte Zwischen-URL zu durchlaufen und zum endgültigen Ziel zu gelangen :

public String expand(String urlArg) throws IOException { String originalUrl = urlArg; String newUrl = expandSingleLevel(originalUrl); while (!originalUrl.equals(newUrl)) { originalUrl = newUrl; newUrl = expandSingleLevel(originalUrl); } return newUrl; }

Definieren wir nun mit dem neuen Mechanismus zum Erweitern mehrerer URL-Ebenen einen Test und setzen diesen um:

@Test public void givenShortenedMultiple_whenUrlIsUnshortened_thenCorrectResult() throws IOException { String expectedResult = "/rest-versioning"; String actualResult = expand("//t.co/e4rDDbnzmk"); assertThat(actualResult, equalTo(expectedResult)); }

Dieses Mal wird die kurze URL - //t.co/e4rDDbnzmk - die tatsächlich zweimal gekürzt wird - einmal über bit.ly und ein zweites Mal über den t.co- Dienst - korrekt auf die ursprüngliche URL erweitert.

4. Auf Umleitungsschleifen erkennen

Schließlich können einige URLs nicht erweitert werden, da sie eine Umleitungsschleife bilden. Diese Art von Problem wird vom HttpClient erkannt , aber da wir die automatische Weiterleitung von Weiterleitungen deaktiviert haben, ist dies nicht mehr der Fall.

Der letzte Schritt im URL-Erweiterungsmechanismus besteht darin, die Umleitungsschleifen zu erkennen und schnell auszufallen, falls eine solche Schleife auftritt.

Damit dies effektiv ist, benötigen wir einige zusätzliche Informationen aus der zuvor definierten expandSingleLevel- Methode. Hauptsächlich müssen wir auch den Statuscode der Antwort zusammen mit der URL zurückgeben.

Da Java nicht mehrere Rückgabewerte unterstützt, werden die Informationen in ein org.apache.commons.lang3.tuple.Pair- Objekt eingeschlossen. Die neue Signatur der Methode lautet nun:

public Pair expandSingleLevelSafe(String url) throws IOException {

Lassen Sie uns abschließend die Erkennung des Umleitungszyklus in den Haupterweiterungsmechanismus aufnehmen:

public String expandSafe(String urlArg) throws IOException { String originalUrl = urlArg; String newUrl = expandSingleLevelSafe(originalUrl).getRight(); List alreadyVisited = Lists.newArrayList(originalUrl, newUrl); while (!originalUrl.equals(newUrl)) { originalUrl = newUrl; Pair statusAndUrl = expandSingleLevelSafe(originalUrl); newUrl = statusAndUrl.getRight(); boolean isRedirect = statusAndUrl.getLeft() == 301 || statusAndUrl.getLeft() == 302; if (isRedirect && alreadyVisited.contains(newUrl)) { throw new IllegalStateException("Likely a redirect loop"); } alreadyVisited.add(newUrl); } return newUrl; }

Und das war's auch schon - der expandSafe- Mechanismus kann URLs verkürzen, die eine beliebige Anzahl von URL-Verkürzungsdiensten durchlaufen, während sie bei Umleitungsschleifen korrekt fehlschlagen.

5. Schlussfolgerung

In diesem Tutorial wurde erläutert, wie Sie kurze URLs in Java mithilfe des Apache HttpClient erweitern .

Wir haben mit einem einfachen Anwendungsfall mit einer URL begonnen, die nur einmal gekürzt wird, und dann einen allgemeineren Mechanismus implementiert, der mehrere Ebenen von Weiterleitungen verarbeiten und dabei Umleitungsschleifen erkennen kann.

Die Implementierung dieser Beispiele finden Sie im Github-Projekt - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.