Ein Leitfaden für Google-Http-Client

Eine Anleitung zum Google-HTTP-Client

1. Überblick

In diesem Artikel werfen wir einen Blick aufGoogle HTTP Client Library for Java, eine schnelle, gut abstrahierte Bibliothek für den Zugriff auf Ressourcen über das HTTP-Verbindungsprotokoll.

Die Hauptmerkmale des Kunden sind:

  • Eine HTTP-Abstraktionsschicht, mit der Sie jede Bibliothek auf niedriger Ebene entkoppeln können

  • Schnelle, effiziente und flexible JSON- und XML-Analysemodelle der HTTP-Antwort und des Anforderungsinhalts

  • Einfach zu verwendende Annotationen und Abstraktionen für HTTP-Ressourcenzuordnungen

Die Bibliothek kann auch in Java 5 und höher verwendet werden, was sie zu einer bedeutenden Wahl für ältere Projekte (SE und EE) macht.

In diesem Artikel werden wir eine einfache Anwendung entwickeln, diewill connect to the GitHub API and retrieve users enthält und gleichzeitig einige der interessantesten Funktionen der Bibliothek behandelt.

2. Maven-Abhängigkeiten

Um die Bibliothek nutzen zu können, benötigen wir die Abhängigkeit vongoogle-http-client:


    com.google.http-client
    google-http-client
    1.23.0

Die neueste Version finden Sie unterMaven Central.

3. Einfache Anfrage stellen

Beginnen wir mit einer einfachen GET-Anfrage an die GitHub-Seite, um zu zeigen, wie der Google Http-Client sofort funktioniert:

HttpRequestFactory requestFactory
  = new NetHttpTransport().createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(
  new GenericUrl("https://github.com"));
String rawResponse = request.execute().parseAsString()

Um die Anfrage so einfach wie möglich zu gestalten, benötigen wir mindestens:

  • HttpRequestFactory Dies wird verwendet, um unsere Anforderungen zu erstellen

  • HttpTransportist eine Abstraktion der HTTP-Transportschicht auf niedriger Ebene

  • GenericUrlist eine Klasse, die die URL umschließt

  • HttpRequest übernimmt die tatsächliche Ausführung der Anforderung

Wir werden all dies und ein komplexeres Beispiel mit einer tatsächlichen API durchgehen, die in den folgenden Abschnitten ein JSON-Format zurückgibt.

4. Steckbarer HTTP-Transport

Die Bibliothek hat eine gut abstrahierteHttpTransport-Klasse, mit der wir darauf aufbauen können, undchange to the underlying low-level HTTP transport library of choice:

public class GitHubExample {
    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
}

In diesem Beispiel verwenden wirNetHttpTransport, das aufHttpURLConnection basiert, die in allen Java SDKs enthalten sind. Dies ist eine gute Ausgangswahl, da sie bekannt und zuverlässig ist.

Natürlich kann es vorkommen, dass wir einige erweiterte Anpassungen benötigen und daher eine komplexere Bibliothek auf niedriger Ebene benötigen.

Für diese Art von Fällen gibt es dieApacheHttpTransport:

public class GitHubExample {
    static HttpTransport HTTP_TRANSPORT = new ApacheHttpTransport();
}

ApacheHttpTransport basiert auf dem beliebtenApache HttpClient, das eine Vielzahl von Optionen zum Konfigurieren von Verbindungen enthält.

Darüber hinaus bietet die Bibliothek die Möglichkeit, Ihre Implementierung auf niedriger Ebene zu erstellen, wodurch sie sehr flexibel wird.

5. JSON-Analyse

Der Google HTTP-Client enthält eine weitere Abstraktion für das JSON-Parsing. Ein Hauptvorteil davon ist, dassthe choice of low-level parsing library is interchangeable.

Es gibt drei integrierte Optionen, die alleJsonFactory, verlängern, und es beinhaltet auch die Möglichkeit, unsere eigenen zu implementieren.

5.1. Austauschbare Analysebibliothek

In unserem Beispiel verwenden wir die Jackson2-Implementierung, für die die Abhängigkeit vongoogle-http-client-jackson2erforderlich ist:


    com.google.http-client
    google-http-client-jackson2
    1.23.0

Anschließend können wir jetzt dieJsonFactory: einschließen

public class GitHubExample {

    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    staticJsonFactory JSON_FACTORY = new JacksonFactory();
}

JacksonFactory ist die schnellste und beliebteste Bibliothek für Parsing- / Serialisierungsvorgänge.

Dies geht zu Lasten der Bibliotheksgröße (was in bestimmten Situationen problematisch sein kann). Aus diesem Grund stellt Google auchGsonFactory zur Verfügung, eine Implementierung der Google GSON-Bibliothek, einer leichten JSON-Parsing-Bibliothek.

Es besteht auch die Möglichkeit, unsere Low-Level-Parser-Implementierung zu schreiben.

5.2. Die Annotation von @Key

Wir können die Annotation@Keyverwenden, um Felder anzugeben, die von JSON analysiert oder serialisiert werden müssen:

public class User {

    @Key
    private String login;
    @Key
    private long id;
    @Key("email")
    private String email;

    // standard getters and setters
}

Hier machen wir eineUser-Abstraktion, die wir stapelweise von der GitHub-API erhalten (wir werden später in diesem Artikel zum eigentlichen Parsen kommen).

Bitte beachten Sie, dassfields that don’t have the @Key annotation are considered internal and are not parsed from or serialized to JSON. Auch die Sichtbarkeit der Felder spielt keine Rolle, ebenso wenig wie die Existenz der Getter- oder Setter-Methoden.

Wir können den Wert der Annotation@Keyangeben, um sie dem richtigen JSON-Schlüssel zuzuordnen.

5.3. GenericJson

Es werden nur die Felder analysiert, die wir deklarieren und als@Key markieren.

Um den anderen Inhalt beizubehalten, können wir unsere Klasse deklarieren, umGenericJson: zu erweitern

public class User extends GenericJson {
    //...
}

GenericJson implementiert die SchnittstelleMap, was bedeutet, dass wir die Methoden get und put verwenden können, um JSON-Inhalte in der Anforderung / Antwort festzulegen / abzurufen.

6. Anruf tätigen

Um mit dem Google Http-Client eine Verbindung zu einem Endpunkt herzustellen, benötigen wir einHttpRequestFactory, das mit unseren vorherigen AbstraktionenHttpTransport undJsonFactory: konfiguriert wird

public class GitHubExample {

    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    static JsonFactory JSON_FACTORY = new JacksonFactory();

    private static void run() throws Exception {
        HttpRequestFactory requestFactory
          = HTTP_TRANSPORT.createRequestFactory(
            (HttpRequest request) -> {
              request.setParser(new JsonObjectParser(JSON_FACTORY));
          });
    }
}

Als nächstes benötigen wir eine URL, zu der eine Verbindung hergestellt werden kann. Die Bibliothek behandelt dies als eine Klasse, dieGenericUrl erweitert, für die jedes deklarierte Feld als Abfrageparameter behandelt wird:

public class GitHubUrl extends GenericUrl {

    public GitHubUrl(String encodedUrl) {
        super(encodedUrl);
    }

    @Key
    public int per_page;

}

Hier in unserenGitHubUrl, deklarieren wir die Eigenschaftper_page, um anzugeben, wie viele Benutzer in einem einzelnen Aufruf der GitHub-API benötigt werden.

Bauen wir unseren Anruf mitGitHubUrl: weiter auf

private static void run() throws Exception {
    HttpRequestFactory requestFactory
      = HTTP_TRANSPORT.createRequestFactory(
        (HttpRequest request) -> {
          request.setParser(new JsonObjectParser(JSON_FACTORY));
        });
    GitHubUrl url = new GitHubUrl("https://api.github.com/users");
    url.per_page = 10;
    HttpRequest request = requestFactory.buildGetRequest(url);
    Type type = new TypeToken>() {}.getType();
    List users = (List)request
      .execute()
      .parseAs(type);
}

Beachten Sie, wie wir angeben, wie viele Benutzer wir für den API-Aufruf benötigen, und erstellen dann die Anforderung mitHttpRequestFactory.

Da die Antwort der GitHub-API eine Liste von Benutzern enthält, müssen wir anschließend ein komplexesType bereitstellen, das einList<User> ist.

In der letzten Zeile rufen wir dann auf und analysieren die Antwort auf eine Liste unsererUser-Klasse.

7. Benutzerdefinierte Header

Eine Sache, die wir normalerweise tun, wenn wir eine API-Anfrage stellen, ist, eine Art benutzerdefinierten Header oder sogar einen modifizierten Header einzuschließen:

HttpHeaders headers = request.getHeaders();
headers.setUserAgent("example Client");
headers.set("Time-Zone", "Europe/Amsterdam");

Dazu erhalten wir dieHttpHeaders, nachdem wir unsere Anforderung erstellt haben, aber bevor wir sie ausführen und die erforderlichen Werte hinzufügen.

Bitte beachten Sie, dass der Google Http-Clientincludes some headers as special methods. DerUser-Agent-Header ist. Wenn wir beispielsweise versuchen, ihn nur mit der festgelegten Methode einzuschließen, wird ein Fehler ausgegeben.

8. Exponentielles Backoff

Ein weiteres wichtiges Feature des Google HTTP-Clients ist die Möglichkeit, Anfragen basierend auf bestimmten Statuscodes und Schwellenwerten erneut zu versuchen.

Wir können unsere exponentiellen Backoff-Einstellungen direkt nach dem Erstellen unseres Anforderungsobjekts einbeziehen:

ExponentialBackOff backoff = new ExponentialBackOff.Builder()
  .setInitialIntervalMillis(500)
  .setMaxElapsedTimeMillis(900000)
  .setMaxIntervalMillis(6000)
  .setMultiplier(1.5)
  .setRandomizationFactor(0.5)
  .build();
request.setUnsuccessfulResponseHandler(
  new HttpBackOffUnsuccessfulResponseHandler(backoff));

Exponential Backoff is turned off by default in HttpRequest, daher müssen wir eine Instanz vonHttpUnsuccessfulResponseHandler zuHttpRequest hinzufügen, um sie zu aktivieren.

9. Protokollierung

Der Google HTTP-Client verwendetjava.util.logging.Logger zum Protokollieren von HTTP-Anforderungs- und Antwortdetails, einschließlich URL, Headern und Inhalten.

In der Regel wird die Protokollierung mit einerlogging.properties-Datei verwaltet:

handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL
com.google.api.client.http.level = ALL

In unserem Beispiel verwenden wirConsoleHandler, aber es ist auch möglich,FileHandler auszuwählen.

Die Eigenschaftendatei konfiguriert den Betrieb der JDK-Protokollierungsfunktion. Diese Konfigurationsdatei kann als Systemeigenschaft angegeben werden:

-Djava.util.logging.config.file=logging.properties

Nach dem Festlegen der Datei- und Systemeigenschaft erstellt die Bibliothek ein Protokoll wie das folgende:

-------------- REQUEST  --------------
GET https://api.github.com/users?page=1&per_page=10
Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip)

Nov 12, 2017 6:43:15 PM com.google.api.client.http.HttpRequest execute
curl -v --compressed -H 'Accept-Encoding: gzip' -H 'User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip)' -- 'https://api.github.com/users?page=1&per_page=10'
Nov 12, 2017 6:43:16 PM com.google.api.client.http.HttpResponse
-------------- RESPONSE --------------
HTTP/1.1 200 OK
Status: 200 OK
Transfer-Encoding: chunked
Server: GitHub.com
Access-Control-Allow-Origin: *
...
Link: ; rel="next", ; rel="first"
X-GitHub-Request-Id: 8D6A:1B54F:3377D97:3E37B36:5A08DC93
Content-Type: application/json; charset=utf-8
...

10. Fazit

In diesem Tutorial haben wir die Google HTTP-Clientbibliothek für Java und ihre nützlicheren Funktionen gezeigt. IhreGithub enthalten weitere Informationen dazu sowie den Quellcode der Bibliothek.

Wie immer ist der vollständige Quellcode dieses Tutorialsover on GitHub verfügbar.