Руководство по Google-Http-Client

Руководство по Google-Http-клиенту

1. обзор

В этой статье мы рассмотримGoogle HTTP Client Library for Java - быструю, хорошо абстрагированную библиотеку для доступа к любым ресурсам через протокол HTTP-соединения.

Основными особенностями клиента являются:

  • уровень абстракции HTTP, который позволяет вам отделить любую низкоуровневую библиотеку

  • быстрые, эффективные и гибкие модели синтаксического анализа JSON и XML для ответа HTTP и содержимого запроса

  • простые в использовании аннотации и абстракции для сопоставления ресурсов HTTP

Библиотека также может использоваться в Java 5 и выше, что делает ее значительным выбором для устаревших (SE и EE) проектов.

В этой статье мы собираемся разработать простое приложениеwill connect to the GitHub API and retrieve users, охватывающее некоторые из наиболее интересных функций библиотеки.

2. Maven Зависимости

Для использования библиотеки нам понадобится зависимостьgoogle-http-client:


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

Последнюю версию можно найти по адресуMaven Central.

3. Делать простой запрос

Давайте начнем с простого запроса GET к странице GitHub, чтобы продемонстрировать, как Google Http Client работает из коробки:

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

Для простейшего запроса нам понадобится как минимум:

  • HttpRequestFactory это используется для построения наших запросов

  • HttpTransport - это абстракция низкоуровневого транспортного уровня HTTP.

  • GenericUrl класс, который обертывает URL-адрес

  • HttpRequest обрабатывает фактическое выполнение запроса

Мы рассмотрим все это, а также более сложный пример с реальным API, который возвращает формат JSON, в следующих разделах.

4. Подключаемый транспорт HTTP

В библиотеке есть хорошо абстрагированный классHttpTransport, который позволяет нам строить поверх него иchange to the underlying low-level HTTP transport library of choice:

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

В этом примере мы используемNetHttpTransport, который основан наHttpURLConnection, который присутствует во всех Java SDK. Это хороший стартовый выбор, поскольку он хорошо известен и надежен.

Конечно, может быть случай, когда нам понадобится расширенная настройка, и, следовательно, потребуется более сложная библиотека низкого уровня.

Для таких случаев существуетApacheHttpTransport:

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

ApacheHttpTransport основан на популярномApache HttpClient, который включает в себя широкий выбор вариантов настройки соединений.

Кроме того, библиотека предоставляет возможность построить низкоуровневую реализацию, что делает ее очень гибкой.

5. JSON Парсинг

Http-клиент Google содержит еще одну абстракцию для анализа JSON. Основным преимуществом этого является то, чтоthe choice of low-level parsing library is interchangeable.

Есть три встроенных варианта, каждый из которых расширяетJsonFactory,, а также включает возможность реализации нашего собственного.

5.1. Сменная библиотека синтаксического анализа

В нашем примере мы собираемся использовать реализацию Jackson2, для которой требуется зависимостьgoogle-http-client-jackson2:


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

После этого мы можем теперь включитьJsonFactory:

public class GitHubExample {

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

JacksonFactory - самая быстрая и популярная библиотека для операций синтаксического анализа / сериализации.

Это происходит за счет размера библиотеки (что может быть проблемой в определенных ситуациях). По этой причине Google также предоставляетGsonFactory, который является реализацией библиотеки Google GSON, облегченной библиотеки синтаксического анализа JSON.

Существует также возможность написания нашей низкоуровневой реализации парсера.

5.2. Аннотация @Key

Мы можем использовать аннотацию@Key, чтобы указать поля, которые необходимо проанализировать или сериализовать в JSON:

public class User {

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

    // standard getters and setters
}

Здесь мы создаем абстракциюUser, которую мы получаем пакетно из API GitHub (мы вернемся к фактическому синтаксическому анализу позже в этой статье).

Обратите внимание, чтоfields that don’t have the @Key annotation are considered internal and are not parsed from or serialized to JSON. Кроме того, видимость полей не имеет значения, равно как и существование методов получения или установки.

Мы можем указать значение аннотации@Key, чтобы сопоставить его с правильным ключом JSON.

5.3. GenericJsonс

Анализируются только те поля, которые мы объявляем и помечаем как@Key.

Чтобы сохранить остальное содержимое, мы можем объявить наш класс расширяющимGenericJson:

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

GenericJson реализует интерфейсMap, что означает, что мы можем использовать методы get и put для установки / получения содержимого JSON в запросе / ответе.

6. Звонок

Чтобы подключиться к конечной точке с помощью Google Http Client, нам понадобитсяHttpRequestFactory, который будет настроен с нашими предыдущими абстракциямиHttpTransport иJsonFactory:.

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

Следующее, что нам понадобится, это URL-адрес для подключения. Библиотека обрабатывает это как класс, расширяющийGenericUrl, в котором любое объявленное поле обрабатывается как параметр запроса:

public class GitHubUrl extends GenericUrl {

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

    @Key
    public int per_page;

}

Здесь, в нашемGitHubUrl,, мы объявляем свойствоper_page, чтобы указать, сколько пользователей мы хотим в одном вызове API GitHub.

Давайте продолжим строить наш вызов, используяGitHubUrl:

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

Обратите внимание, как мы указываем, сколько пользователей нам понадобится для вызова API, а затем создаем запрос сHttpRequestFactory.

После этого, поскольку ответ API GitHub содержит список пользователей, нам нужно предоставить комплексныйType, который являетсяList<User>.

Затем, в последней строке, мы выполняем вызов и анализируем ответ на список нашего классаUser.

7. Пользовательские Заголовки

Одна вещь, которую мы обычно делаем при создании запроса API - это добавление какого-либо пользовательского заголовка или даже модифицированного:

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

Мы делаем это, получаяHttpHeaders после того, как мы создали наш запрос, но перед его выполнением и добавлением необходимых значений.

Имейте в виду, что Google Http Clientincludes some headers as special methods. ЗаголовокUser-Agent, например, если мы попытаемся включить его только с помощью метода set, это вызовет ошибку.

8. Экспоненциальный откат

Еще одна важная функция Google Http Client - это возможность повторять запросы на основе определенных кодов состояния и пороговых значений.

Мы можем включить наши настройки экспоненциальной отсрочки сразу после создания объекта запроса:

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, поэтому мы должны включить экземплярHttpUnsuccessfulResponseHandler вHttpRequest, чтобы активировать его.

9. логирование

Клиент Google Http используетjava.util.logging.Logger для регистрации деталей HTTP-запроса и ответа, включая URL-адрес, заголовки и контент.

Обычно ведение журнала управляется с помощью файлаlogging.properties:

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

В нашем примере мы используемConsoleHandler, но также можно выбратьFileHandler.

Файл свойств настраивает работу средства ведения журнала JDK. Этот конфигурационный файл может быть указан как системное свойство:

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

Таким образом, после установки свойства file и system библиотека создаст журнал, подобный следующему:

-------------- 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. Заключение

В этом руководстве мы показали клиентскую библиотеку HTTP Google для Java и ее более полезные функции. ИхGithub содержит больше информации об этом, а также исходный код библиотеки.

Как всегда, доступен полный исходный код этого руководстваover on GitHub.