Un guide pour Google-Http-Client

Un guide pour Google-Http-Client

1. Vue d'ensemble

Dans cet article, nous allons jeter un œil àGoogle HTTP Client Library for Java, qui est une bibliothèque rapide et bien abstraite pour accéder à toutes les ressources via le protocole de connexion HTTP.

Les principales caractéristiques du client sont:

  • une couche d'abstraction HTTP qui vous permet de découpler toute bibliothèque de bas niveau

  • modèles d'analyse JSON et XML rapides, efficaces et flexibles de la réponse HTTP et du contenu de la requête

  • annotations et abstractions faciles à utiliser pour les mappages de ressources HTTP

La bibliothèque peut également être utilisée dans Java 5 et versions ultérieures, ce qui en fait un choix considérable pour les projets hérités (SE et EE).

Dans cet article, nous allons développer une application simple quiwill connect to the GitHub API and retrieve users, tout en couvrant certaines des fonctionnalités les plus intéressantes de la bibliothèque.

2. Dépendances Maven

Pour utiliser la bibliothèque, nous aurons besoin de la dépendancegoogle-http-client:


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

La dernière version peut être trouvée àMaven Central.

3. Faire une demande simple

Commençons par envoyer une simple requête GET à la page GitHub pour montrer comment fonctionne le client Google Http prêt à l'emploi:

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

Pour faire la demande la plus simple, nous aurons au moins besoin:

  • HttpRequestFactory ceci est utilisé pour construire nos requêtes

  • HttpTransport une abstraction de la couche de transport HTTP de bas niveau

  • GenericUrl une classe qui encapsule l'URL

  • HttpRequest gère l'exécution réelle de la requête

Nous allons passer en revue tout cela et un exemple plus complexe avec une API réelle qui renvoie un format JSON dans les sections suivantes.

4. Transport HTTP enfichable

La bibliothèque a une classeHttpTransport bien abstraite qui nous permet de construire dessus etchange to the underlying low-level HTTP transport library of choice:

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

Dans cet exemple, nous utilisons lesNetHttpTransport, qui sont basés sur lesHttpURLConnection qui se trouvent dans tous les SDK Java. C'est un bon choix de départ car il est bien connu et fiable.

Bien sûr, il peut arriver que nous ayons besoin d’une personnalisation avancée, et donc de la nécessité d’une bibliothèque de bas niveau plus complexe.

Pour ce genre de cas, il y a lesApacheHttpTransport:

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

LeApacheHttpTransport est basé sur le populaireApache HttpClient qui comprend une grande variété de choix pour configurer les connexions.

De plus, la bibliothèque offre la possibilité de construire votre implémentation de bas niveau, ce qui la rend très flexible.

5. Analyse JSON

Le client Google Http comprend une autre abstraction pour l'analyse JSON. Un avantage majeur de ceci est quethe choice of low-level parsing library is interchangeable.

Il existe trois choix intégrés, qui étendent tousJsonFactory, et qui incluent également la possibilité de mettre en œuvre le nôtre.

5.1. Bibliothèque d'analyse interchangeable

Dans notre exemple, nous allons utiliser l'implémentation Jackson2, qui nécessite la dépendancegoogle-http-client-jackson2:


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

Suite à cela, nous pouvons maintenant inclure lesJsonFactory:

public class GitHubExample {

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

LaJacksonFactory est la bibliothèque la plus rapide et la plus populaire pour les opérations d'analyse / sérialisation.

Cela se fait au prix de la taille de la bibliothèque (ce qui peut poser problème dans certaines situations). Pour cette raison, Google fournit également leGsonFactory, qui est une implémentation de la bibliothèque Google GSON, une bibliothèque d'analyse JSON légère.

Il est également possible d’écrire notre implémentation d’analyseur de bas niveau.

5.2. L'annotation @Key

Nous pouvons utiliser l'annotation@Key pour indiquer les champs qui doivent être analysés ou sérialisés vers JSON:

public class User {

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

    // standard getters and setters
}

Nous faisons ici une abstraction deUser, que nous recevons par lots de l'API GitHub (nous reviendrons à l'analyse réelle plus loin dans cet article).

Veuillez noter quefields that don’t have the @Key annotation are considered internal and are not parsed from or serialized to JSON. De plus, la visibilité des champs n'a pas d'importance, pas plus que l'existence des méthodes getter ou setter.

Nous pouvons spécifier la valeur de l'annotation@Key, pour la mapper à la clé JSON correcte.

5.3. GenericJson

Seuls les champs que nous déclarons et marquons comme@Key sont analysés.

Pour conserver l'autre contenu, nous pouvons déclarer notre classe pour étendreGenericJson:

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

GenericJson implémente l'interfaceMap, ce qui signifie que nous pouvons utiliser les méthodes get et put pour définir / obtenir le contenu JSON dans la requête / réponse.

6. Faire l'appel

Pour nous connecter à un point de terminaison avec le client Http Google, nous aurons besoin d'unHttpRequestFactory, qui sera configuré avec nos abstractions précédentesHttpTransport etJsonFactory:

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

La prochaine chose dont nous aurons besoin est une URL à laquelle nous connecter. La bibliothèque gère cela comme une classe étendantGenericUrl sur laquelle tout champ déclaré est traité comme un paramètre de requête:

public class GitHubUrl extends GenericUrl {

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

    @Key
    public int per_page;

}

Ici, dans nosGitHubUrl,, nous déclarons la propriétéper_page pour indiquer le nombre d'utilisateurs que nous voulons en un seul appel à l'API GitHub.

Continuons à construire notre appel en utilisant lesGitHubUrl:

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

Remarquez comment nous spécifions le nombre d'utilisateurs dont nous aurons besoin pour l'appel API, puis nous construisons la demande avec lesHttpRequestFactory.

Ensuite, puisque la réponse de l'API GitHub contient une liste d'utilisateurs, nous devons fournir unType complexe, qui est unList<User>.

Ensuite, sur la dernière ligne, nous faisons l'appel et analysons la réponse à une liste de notre classeUser.

7. En-têtes personnalisés

Une des choses que nous faisons habituellement lorsque nous faisons une demande d’API consiste à inclure une sorte d’en-tête personnalisé ou même modifié:

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

Pour ce faire, nous obtenons lesHttpHeaders après avoir créé notre requête mais avant de l'exécuter et d'ajouter les valeurs nécessaires.

Veuillez noter que le client Http Googleincludes some headers as special methods. L'en-têteUser-Agent par exemple, si nous essayons de l'inclure uniquement avec la méthode définie, cela générerait une erreur.

8. Retard exponentiel

Une autre caractéristique importante du client Google Http est la possibilité de réessayer les demandes en fonction de certains codes d’état et de certains seuils.

Nous pouvons inclure nos paramètres d'interruption exponentielle juste après avoir créé notre objet de requête:

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, nous devons donc inclure une instance deHttpUnsuccessfulResponseHandler auHttpRequest pour l'activer.

9. Enregistrement

Le client Http Google utilisejava.util.logging.Logger pour consigner les détails des requêtes et réponses HTTP, y compris l'URL, les en-têtes et le contenu.

Généralement, la journalisation est gérée à l'aide d'un fichierlogging.properties:

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

Dans notre exemple, nous utilisonsConsoleHandler, mais il est également possible de choisir lesFileHandler.

Le fichier de propriétés configure le fonctionnement de la fonction de journalisation JDK. Ce fichier de configuration peut être spécifié en tant que propriété système:

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

Ainsi, après avoir défini les propriétés du fichier et du système, la bibliothèque produira un journal du type suivant:

-------------- 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. Conclusion

Dans ce didacticiel, nous avons présenté la bibliothèque cliente HTTP de Google pour Java et ses fonctionnalités les plus utiles. LeurGithub contient plus d'informations à ce sujet ainsi que le code source de la bibliothèque.

Comme toujours, le code source complet de ce tutoriel est disponibleover on GitHub.