Ein Leitfaden für Google-Http-Client

1. Übersicht

In diesem Artikel werfen wir einen Blick auf die Google HTTP-Clientbibliothek für 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-Parsing-Modelle der HTTP-Antwort und des Anforderungsinhalts
  • Einfach zu verwendende Anmerkungen und Abstraktionen für HTTP-Ressourcenzuordnungen

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

In diesem Artikel werden wir eine einfache Anwendung entwickeln, die eine Verbindung zur GitHub-API herstellt und Benutzer abruft , während einige der interessantesten Funktionen der Bibliothek behandelt werden.

2. Maven-Abhängigkeiten

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

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

Die neueste Version finden Sie bei Maven Central.

3. Eine 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("//github.com")); String rawResponse = request.execute().parseAsString()

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

  • HttpRequestFactory Hiermit werden unsere Anforderungen erstellt
  • HttpTransport eine Abstraktion der HTTP-Transportschicht auf niedriger Ebene
  • GenericUrl 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 verfügt über eine gut abstrahierte HttpTransport- Klasse, mit der wir darauf aufbauen und zur zugrunde liegenden HTTP-Transportbibliothek auf niedriger Ebene Ihrer Wahl wechseln können :

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

In diesem Beispiel verwenden wir den NetHttpTransport , der auf der HttpURLConnection basiert, die in allen Java SDKs enthalten ist. Dies ist eine gute Startwahl, 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 den ApacheHttpTransport:

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

Der ApacheHttpTransport basiert auf dem beliebten Apache HttpClient, der 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 ist.

5. JSON-Analyse

Der Google Http-Client enthält eine weitere Abstraktion für die JSON-Analyse. Ein wesentlicher Vorteil davon ist, dass die Auswahl der Parsing-Bibliothek auf niedriger Ebene austauschbar ist .

Es gibt drei integrierte Optionen, die alle JsonFactory erweitern, und es bietet 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 von Google-http-client-jackson2 erforderlich ist:

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

Anschließend können wir jetzt die JsonFactory einbinden:

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

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

Dies geht zu Lasten der Bibliotheksgröße (was in bestimmten Situationen ein Problem sein kann). Aus diesem Grund bietet Google auch die GsonFactory an , 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 @ Key Annotation

Wir können die @ Key- Annotation verwenden, 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 eine Benutzerabstraktion , die wir im Stapel von der GitHub-API erhalten (wir werden später in diesem Artikel zum eigentlichen Parsen kommen) .

Bitte beachten Sie, dass Felder ohne die @ Key- Annotation als intern betrachtet werden und nicht von JSON analysiert oder serialisiert werden . Auch die Sichtbarkeit der Felder spielt keine Rolle, ebenso wenig wie die Existenz der Getter- oder Setter-Methoden.

Wir können den Wert der @ Key- Annotation angeben , 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, um GenericJson zu erweitern :

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

GenericJson implementiert die Map- Schnittstelle. Dies 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 eine HttpRequestFactory , die mit unseren vorherigen Abstraktionen HttpTransport und JsonFactory 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)); }); } }

Das nächste, was wir brauchen, ist eine URL, mit der wir uns verbinden können. Die Bibliothek behandelt dies als eine Klasse, die GenericUrl 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 unserer GitHubUrl deklarieren wir die Eigenschaft per_page, um anzugeben, wie viele Benutzer in einem einzelnen Aufruf der GitHub-API benötigt werden.

Lassen Sie uns unseren Aufruf mit GitHubUrl fortsetzen:

private static void run() throws Exception { HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory( (HttpRequest request) -> { request.setParser(new JsonObjectParser(JSON_FACTORY)); }); GitHubUrl url = new GitHubUrl("//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); }
    

Notice how we specify how many users we'll need for the API call, and then we build the request with the HttpRequestFactory.

Following this, since the GitHub API's response contains a list of users, we need to provide a complex Type, which is a List.

Then, on the last line, we make the call and parse the response to a list of our User class.

7. Custom Headers

One thing we usually do when making an API request is to include some kind of custom header or even a modified one:

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

We do this by getting the HttpHeaders after we've created our request but before executing it and adding the necessary values.

Please be aware that the Google Http Client includes some headers as special methods. The User-Agent header for example, if we try to include it with just the set method it would throw an error.

8. Exponential Backoff

Another important feature of the Google Http Client is the possibility to retry requests based on certain status codes and thresholds.

We can include our exponential backoff settings right after we've created our request object:

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, so we must include an instance of HttpUnsuccessfulResponseHandler to the HttpRequest to activate it.

9. Logging

The Google Http Client uses java.util.logging.Logger for logging HTTP request and response details, including URL, headers, and content.

Commonly, logging is managed using a logging.properties file:

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

In our example we use ConsoleHandler, but it's also possible to choose the FileHandler.

The properties file configures the operation of the JDK logging facility. This config file can be specified as a system property:

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

So after setting the file and system property, the library will produce a log like the following:

-------------- REQUEST -------------- GET //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)' -- '//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. Conclusion

In this tutorial, we've shown the Google HTTP Client Library for Java and its more useful features. Their Github contains more information about it as well as the source code of the library.

Wie immer ist der vollständige Quellcode dieses Tutorials auf GitHub verfügbar.