Verkleinerung von URLs mit HttpClient

Heben Sie die Verkürzung von URLs mit HttpClient auf

1. Überblick

In diesem Artikel zeigen wir, wie manunshorten an URLs usingHttpClient macht.

Ein einfaches Beispiel ist, wennthe original URL has been shortened once - von einem Dienst wiebit.ly.

Ein komplexeres Beispiel ist, wennthe URL has been shortened multiple times von verschiedenen solchen Diensten stammt 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 zuthe main 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, derdoesn’t automatically follow redirects:

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, ist301 Moved Permanently.

Dann müssen wirextract the Location header auf die nächste zeigen, und in diesem Fall - 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("http://bit.ly/13jEoS1");
    assertThat(actualResult, equalTo(expectedResult));
}

3. Mehrere URL-Ebenen verarbeiten

Das Problem bei kurzen URLs besteht darin, dass sie von insgesamt verschiedenen Dienstenshortened multiple times sein können. Das Erweitern einer solchen URL erfordert mehrere Durchgänge, um zur ursprünglichen URL zu gelangen.

Wir werden die zuvor definierte primitive OperationexpandSingleLevelauf einfachiterate through all the intermediary URL and get to the final target anwenden:

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

Mit dem neuen Mechanismus zur Erweiterung mehrerer URL-Ebenen definieren wir nun einen Test und setzen ihn um:

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

Dieses Mal wird die kurze URL -http://t.co/e4rDDbnzmk - die tatsächlich zweimal gekürzt wird - einmal überbit.ly und ein zweites Mal über den Dienstt.co- 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 vonHttpClient erkannt, aber da wir die automatische Verfolgung von Weiterleitungen deaktiviert haben, ist dies nicht mehr der Fall.

Der letzte Schritt im URL-Erweiterungsmechanismus ist das Erkennen der Umleitungsschleifen und das schnelle Fehlschlagen, falls eine solche Schleife auftritt.

Damit dies effektiv ist, benötigen wir einige zusätzliche Informationen aus der zuvor definiertenexpandSingleLevel-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, gehen wir zuwrap the information in a org.apache.commons.lang3.tuple.Pair object - 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 - derexpandSafe-Mechanismus kann URLs verkürzen, die eine beliebige Anzahl von URL-Verkürzungsdiensten durchlaufen, während sie in Umleitungsschleifen korrekt schnell fehlschlagen.

5. Fazit

In diesem Tutorial wurde erläutert, wieexpand short URLs in java - mit dem ApacheHttpClient.

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

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