1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/troyzhxu-httputils

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README-2.0.0.md 25 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 26.11.2024 02:06 bb668ec

HttpUtils

Введение

HttpUtils — это набор инструментов, основанный на OkHttp, который предоставляет автоматическую обработку и удобный для использования в цепочке, асинхронный и синхронный режимы, а также универсальность для переднего и заднего плана.

  • Поддержка асинхронных и синхронных запросов.
  • Поддержка стиля Restfull.
  • Автоматическая упаковка и распаковка JSON.
  • Пул соединений TCP.
  • Перехватчики запросов.
  • HTTP/2.
  • Конфигурация потока обратного вызова.
  • Асинхронные предварительные обработчики.
  • GET, POST, PUT, DELETE.
  • Загрузка и скачивание файлов.

Текущая версия документа 2.0.0 см. 1.x.x здесь

Инструкция по установке

Maven

<dependency>
     <groupId>com.ejlchina</groupId>
     <artifactId>httputils</artifactId>
     <version>2.0.0</version>
</dependency>

Gradle

compile 'com.ejlchina:httputils:2.0.0'

Использование

HttpResult result = http.sync("http://api.demo.com/users/1").delete();  // Синхронный DELETE

HttpCall call = http.async("http://api.demo.com/users/1")
        .setOnResponse((HttpResult result) -> {
        
        })
        .delete();                                                      // Асинхронный DELETE

// 3. Анализ и выполнение результатов

3.1 Функции обратного вызова

Только асинхронные запросы могут устанавливать функции обратного вызова:

http.async("http://api.demo.com/users/1")
        .setOnResponse((HttpResult result) -> {
            // Ответный обратный вызов
        })
        .setOnException((Exception e) -> {
            // Обратный вызов исключения
        })
        .setOnComplete((State state) -> {
            // Завершающий обратный вызов, выполняется независимо от успеха или неудачи
        })
        .get();

Все методы синхронного запроса возвращают объект HttpResult, все методы асинхронного запроса возвращают объект HttpCall.

3.2 Объект HttpResult

Объект HttpResult представляет собой результат выполнения HTTP-запроса после его завершения. Он является возвращаемым значением методов синхронного запроса (get, post, put, delete) и параметром обратного вызова ответа (OnResponse) для асинхронных запросов. У него есть следующие методы:

  • getState() — возвращает перечисление состояния запроса, которое может иметь следующие значения:
    • State.CANCELED — запрос отменён;
    • State.RESPONSED — получен ответ;
    • State.TIMEOUT — запрос превысил время ожидания;
    • State.NETWORK_ERROR — сетевая ошибка;
    • State.EXCEPTION — другое исключение запроса.
  • getStatus() — получает код состояния HTTP.
  • isSuccessful() — определяет, был ли ответ успешным, код состояния находится в диапазоне [200..300).
  • getHeaders() — получает заголовки HTTP-ответа.
  • getBody() — получает тело ответа. У тела ответа есть следующие методы:
    • toBytes() — возвращает массив байтов;
    • toByteStream() — возвращает поток байтов ввода;
    • toCharStream() — возвращает символьный поток ввода;
    • toString() — возвращает строку;
    • toJsonObject() — преобразует в объект Json;
    • toJsonArray() — преобразует в массив Json;
    • toBean(Class type) — преобразует в JavaBean на основе типа;
    • toBean(TypeReference type) — преобразует в JavaBean на основе typeReference;
    • toFile(String filePath) — загружает файл в указанный каталог и возвращает сохранённый файл (полезно при загрузке файлов);
    • toFile(File file) — загружает файл в указанный файл и возвращает сохранённый файл (полезно при загрузке файлов);
    • getContentType() — возвращает тип содержимого тела сообщения;
    • getContentLength() — возвращает длину тела сообщения в байтах. Для одного и того же объекта Body можно использовать только один из методов toXXX() и только один раз.
  • getError() — исключение, возникшее во время выполнения запроса, автоматически перехватывает сетевые тайм-ауты, сетевые ошибки и другие исключения запросов. Например, загрузка файла в указанный каталог:
String path = "D:/reports/2020-03-01.xlsx"; // Каталог сохранения

// Синхронная загрузка
http.sync("http://api.demo.com/reports/2020-03-01.xlsx")
        .get().getBody().toFile(path);

// Асинхронная загрузка
http.async("http://api.demo.com/reports/2020-03-01.xlsx")
        .setOnResponse((HttpResult result) -> {
            result.getBody().toFile(path);
        })
        .get();

3.3 Объект HttpCall

Объект HttpCall является результатом асинхронного метода запроса (get, post, put, delete). Он похож на интерфейс Future в java. У него есть следующие методы:

  • cancel() — отменяет текущий запрос и возвращает результат отмены.
  • isCanceled() — проверяет, был ли запрос отменён.
  • isDone() — проверяет, выполнен ли запрос, включая отмену и сбой.
  • getResult() — возвращает объект результата выполнения HttpResult. Если запрос не завершён, он блокирует текущий поток до завершения запроса. Пример отмены асинхронного запроса:
HttpCall call = http.async("http://api.demo.com/users/1").get();

System.out.println(call.isCanceled());   // false

boolean success = call.cancel();   // Отмена запроса

System.out.println(success);             // true
System.out.println(call.isCanceled());   // true

4 Построение HTTP-задачи

Методы sync и async объекта HTTP возвращают объект задачи HttpTask. Этот объект предоставляет ряд методов addXXX, setXXX и tag для построения самой задачи.

4.1 Добавление заголовка запроса

Однократное добавление (методы синхронизации и асинхронизации одинаковы):

http.sync("http://api.demo.com/orders")
        .addHeader("Access-Token", "xxxxxx")
        .addHeader("Content-Type", "application/json")
        .get();

Добавление нескольких заголовков (методы синхронизации и асинхронизации одинаковы):

Map<String, String> headers = new HashMap<>()
headers.put("Access-Token", "xxxxxx");
headers.put("Accept", "application/json");

http.sync("http://api.demo.com/orders")
        .addHeader(headers)
        .get();

4.2 Добавление параметров пути

Параметры пути используются для замены заполнителей в строке URL. Однократное добавление (методы синхронизации и асинхронизации одинаковы):

http.sync("http://api.demo.com/shops/{shopName}/products/{productId}")
        .addPathParam("shopName", "taobao")
        .addPathParam("productId", 20)
        .get();

Добавление нескольких параметров пути (методы синхронизации и асинхронизации одинаковы):

Map<String, String> params = new HashMap<>()
params.put("shopName", "taobao");
params.put("productId", 20);

http.sync("http://api.demo.com/shops/{shopName}/products/{productId}")
        .addPathParam(params)
        .get();

4.3 Добавление параметров запроса

Параметры запроса (параметры URL) используются для добавления строки запроса после символа ? в URL. Однократное добавление (методы синхронизации и асинхронизации одинаковы): http.sync("http://api.demo.com/products")

.addUrlParam("name", "手机")

.addUrlParam("type", "5G")

.get();

Добавление параметров URL.

Несколько добавлений (синхронный и асинхронный методы одинаковы):

Map<String, String> params = new HashMap<>();
params.put("name", "телефон");
params.put("type", "5G");

http.sync("http://api.demo.com/products")
    .addUrlParam(params)
    .get();

4.4 Добавление параметров формы

Параметры формы передаются в теле запроса в формате key=value&.

Однократное добавление (синхронный и асинхронный методы одинаковы):

http.sync("http://api.demo.com/signin")
    .addBodyParam("username", "Джексон")
    .addBodyParam("password", "xxxxxx")
    .post();

Множественное добавление (синхронный и асинхронный методы одинаковы):

Map<String, String> params = new HashMap<>();
params.put("username", "Джексон");
params.put("password", "xxxxxx");

http.sync("http://api.demo.com/signin")
    .addBodyParam(params)
    .post();

4.5 Добавление параметров JSON

JSON-параметры передаются в виде строки JSON в теле запроса.

Однократное добавление (синхронный и асинхронный методы одинаковы):

http.sync("http://api.demo.com/signin")
    .addJsonParam("username", "Jackson")
    .addJsonParam("password", "xxxxx")
    .post();

Множественное добавление (синхронный и асинхронный методы одинаковы):

Map<String, String> params = new HashMap<>;
params.put("username", "Джексон");
params.put("password", "xxxxxx");

http.sync("http://api.demo.com/signin")
    .addJsonParam(params)
    .post();

Прямое задание строки JSON:

http.sync("http://api.demo.com/signin")
    .setRequestJson("\"username\":\"Джексон\",\"password\":\"xxxxxx\"")
    .post();

Автоматическое преобразование JavaBean в JSON:

Login login = new Login();
login.setUsername("Джексон");
login.setPassword("xxxxxx");

http.sync("http://api.demo.com/signin")
    .setRequestJson(login)
    .post();

4.6 Добавление параметров файла

Загрузка локальных файлов:

File file1 = new File("D:/1.jpg");
File file2 = new File("D:/2.jpg");

http.sync("http://api.demo.com/upload")
    .addFileParam("image1", file1)
    .addFileParam("image2", file2)
    .post();

Использование потока ввода файла для загрузки:

// Получение потока ввода файла
InputStream input = ...

http.sync("http://api.demo.com/upload")
    .addFileParam("image", "jpg", input)
    .post();

Использование массива байтов файла для загрузки:

// Получение массива байтов файла
byte[] content = ...

http.sync("http://api.demo.com/upload")
    .addFileParam("image", "jpg", content)
    .post();

Файл и параметры формы могут быть добавлены вместе:

File file = new File("D:/首页广告.jpg");

http.sync("http://api.demo.com/messages")
    .addBodyParam("name", "рекламное изображение")
    .addFileParam("изображение", файл)
    .post();

4.7 Добавление тегов

Иногда мы классифицируем HTTP-задачи с помощью тегов:

http.async("http://api.demo.com/users")
    .tag("MyTag")
    .get();

После использования тегов можно отменить все задачи с этим тегом:

http.cancel("MyTag");

Также можно использовать теги для классификации задач в централизованных препроцессорах (см. разделы «Параллельный препроцессор» и «Последовательный препроцессор»).

5 Настройка HTTP

5.1 Установка BaseUrl

HTTP http = HTTP.builder()
    .baseUrl("http://api.demo.com") // установка BaseUrl
    .build();

Эта конфигурация действует глобально. После настройки BaseUrl конкретные запросы могут опускать часть BaseUrl, что делает код более лаконичным:

http.sync("/users").get() // http://api.demo.com/users

http.sync("/auth/signin") // POST-запрос
    .addBodyParam("имя пользователя", "Джексон")
    .addBodyParam("пароль", "xxxxxx")
    .post()

Если есть специальные задачи запросов, вы всё равно можете использовать полный путь, это не помешает:

http.sync("https://www.baidu.com").get()

5.2 Исполнитель обратного вызова

Чтобы изменить поток выполнения функции обратного вызова, можно настроить функцию обратного вызова. Например, в Android, чтобы все функции обратного вызова выполнялись в потоке пользовательского интерфейса, настройте функцию обратного вызова при создании HTTP:

HTTP http = HTTP.builder()
    .callbackExecutor((Runnable run) -> {
        runOnUiThread(run); // выполнение в потоке UI
    })
    .build();

5.3 Настройка OkHttpClient

В отличие от других фреймворков, которые скрывают OkHttp, HttpUtils не скрывает полезные функции OkHttp:

HTTP http = HTTP.builder()
.config((Builder builder) -> {
    // настройка пула соединений (минимум 10 соединений, по умолчанию 5)
    builder.connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES));
    // настройка времени ожидания соединения
    builder.connectTimeout(20, TimeUnit.SECONDS);
    // настройка перехватчика
    builder.addInterceptor((Chain chain) -> {
        Request request = chain.request();
        //
``` **Необходимо синхронизировать возврат, в перехватчике невозможно выполнить асинхронную операцию**

    return chain.proceed(request);
});
// Другие конфигурации: SSL, кэш, прокси, прослушивание событий...
})
.build();

#### 5.4 Параллельный препроцессор

Препроцессор (Preprocessor) позволяет нам вносить некоторые изменения в сам запрос перед его отправкой, но в отличие от перехватчика (Interceptor), предоставляемого OkHttp, препроцессор позволяет обрабатывать эти проблемы асинхронно.

Например, когда мы хотим автоматически добавить информацию заголовка «Token» к задаче запроса, а «Token» можно получить только с помощью асинхронного метода requestToken, использование перехватчика становится затруднительным, но мы можем легко решить эту проблему с помощью препроцессора:

```java
HTTP http = HTTP.builder()
        .addPreprocessor((Process process) -> {
            HttpTask<?> task = process.getTask();       // Получить текущую задачу запроса
            String tag = task.getTag();                 // Получить метку, добавленную к задаче
            if (!"Auth".equals(tag)) {                  // Определить, требуется ли токен для этой задачи на основе метки
                return;
            }
            requestToken((String token) -> {            // Асинхронное получение токена
                task.addHeader("Token", token);         // Добавить токен в заголовок задачи
                process.proceed();                      // Продолжить текущую задачу
            }); 
        })
        .build();

Как и перехватчик, можно добавить несколько препроцессоров.

5.5 Последовательный препроцессор

Обычные препроцессоры могут обрабатываться параллельно, но иногда мы хотим, чтобы один препроцессор обрабатывал только одну задачу за раз. Например, если срок действия «Token» истёк, нам нужно обновить его, и операция обновления «Token» может быть выполнена только одной задачей за раз, поскольку если бы n задач выполнялись одновременно, то n-1 задач могли бы немедленно использовать обновлённый «Token», который уже истёк, что нежелательно.

Чтобы решить эту проблему, HttpUtils предоставляет последовательный препроцессор, который позволяет задачам HTTP выстраиваться в очередь и входить в препроцессор по очереди:

HTTP http = HTTP.builder()
        .addSerialPreprocessor((Process process) -> {
            HttpTask<?> task = process.getTask();       // Получить текущую задачу запроса
            String tag = task.getTag();                 // Получить метку, добавленную к задаче
            if (!"Auth".equals(tag)) {                  // Определить, требуется ли токен для этой задачи на основе метки
                return;
            }
            // Проверить срок действия, обновить токен при необходимости
            requestTokenAndRefreshIfExpired((String token) -> {
                task.addHeader("Token", token);         // Добавить токен в заголовок задачи
                process.proceed();                      // Вызов этого метода не позволит другим задачам войти в этот обработчик
            }); 
        })
        .build();

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

Участие и вклад

  1. Форк этого репозитория.
  2. Создайте ветку Feat_xxx.
  3. Отправьте код.
  4. Создайте Pull Request.

Навыки работы с кодом Cloud

  1. Используйте Readme_XXX.md для поддержки разных языков, например Readme_en.md, Readme_zh.md.
  2. Официальный блог Code Cloud blog.gitee.com.
  3. Вы можете https://gitee.com/explore этот адрес, чтобы узнать о выдающихся проектах с открытым исходным кодом на Code Cloud.
  4. GVP (GVP) — это аббревиатура от самых ценных проектов с открытым исходным кодом Code Cloud, которые являются выдающимися проектами с открытым исходным кодом, выбранными Code Cloud.
  5. Официальное руководство Code Cloud https://gitee.com/help.
  6. Code Cloud Official Cover Person — это серия, демонстрирующая стиль членов Code Cloud https://gitee.com/gitee-stars/.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/troyzhxu-httputils.git
git@api.gitlife.ru:oschina-mirror/troyzhxu-httputils.git
oschina-mirror
troyzhxu-httputils
troyzhxu-httputils
master