«1. Обзор

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

Основные функции клиента:

    Уровень абстракции HTTP, который позволяет отделить любую низкоуровневую библиотеку. Быстрые, эффективные и гибкие модели синтаксического анализа JSON и XML для HTTP-ответа и содержимого запроса. для сопоставления ресурсов HTTP

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

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

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

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

<dependency>
    <groupId>com.google.http-client</groupId>
    <artifactId>google-http-client</artifactId>
    <version>1.23.0</version>
</dependency>

Последнюю версию можно найти на 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, который позволяет нам строить поверх него и переходить к базовой низкоуровневой транспортной библиотеке HTTP по выбору:

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

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

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

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

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

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

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

5. Анализ JSON

Клиент Google Http включает еще одну абстракцию для анализа JSON. Основным преимуществом этого является то, что выбор низкоуровневой библиотеки синтаксического анализа является взаимозаменяемым.

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

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

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

<dependency>
    <groupId>com.google.http-client</groupId>
    <artifactId>google-http-client-jackson2</artifactId>
    <version>1.23.0</version>
</dependency>

Теперь мы можем включить 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
}

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

Обратите внимание, что поля без аннотации @Key считаются внутренними и не анализируются и не сериализуются в 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, в котором любое объявленное поле обрабатывается как параметр запроса: Гитхаб API.

public class GitHubUrl extends GenericUrl {

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

    @Key
    public int per_page;
 
}

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

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

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<List<User>>() {}.getType();
    List<User> users = (List<User>)request
      .execute()
      .parseAs(type);
}

После этого, поскольку ответ GitHub API содержит список пользователей, нам нужно указать сложный тип, то есть List\u003cUser\u003e.

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

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

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

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

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

Имейте в виду, что HTTP-клиент Google включает некоторые заголовки в качестве специальных методов. Например, заголовок User-Agent, если мы попытаемся включить его только с помощью метода set, это вызовет ошибку.

8. Экспоненциальная отсрочка

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

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

Экспоненциальная отсрочка по умолчанию отключена в HttpRequest, поэтому мы должны включить экземпляр HttpUnsuccessfulResponseHandler в HttpRequest, чтобы активировать его. .

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

9. Ведение журнала

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

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

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

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

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

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

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

10. Заключение

-------------- 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: <https://api.github.com/users?page=1&per_page=10&since=19>; rel="next", <https://api.github.com/users{?since}>; rel="first"
X-GitHub-Request-Id: 8D6A:1B54F:3377D97:3E37B36:5A08DC93
Content-Type: application/json; charset=utf-8
...

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

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

«