HttpUtils — это набор инструментов, основанный на OkHttp, который предоставляет автоматическую обработку и удобный для использования в цепочке, асинхронный и синхронный режимы, а также универсальность для переднего и заднего плана.
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>httputils</artifactId>
<version>2.0.0</version>
</dependency>
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. Анализ и выполнение результатов
Только асинхронные запросы могут устанавливать функции обратного вызова:
http.async("http://api.demo.com/users/1")
.setOnResponse((HttpResult result) -> {
// Ответный обратный вызов
})
.setOnException((Exception e) -> {
// Обратный вызов исключения
})
.setOnComplete((State state) -> {
// Завершающий обратный вызов, выполняется независимо от успеха или неудачи
})
.get();
Все методы синхронного запроса возвращают объект HttpResult, все методы асинхронного запроса возвращают объект HttpCall.
Объект HttpResult представляет собой результат выполнения HTTP-запроса после его завершения. Он является возвращаемым значением методов синхронного запроса (get, post, put, delete) и параметром обратного вызова ответа (OnResponse) для асинхронных запросов. У него есть следующие методы:
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();
Объект HttpCall является результатом асинхронного метода запроса (get, post, put, delete). Он похож на интерфейс Future в java. У него есть следующие методы:
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
Методы sync и async объекта HTTP возвращают объект задачи HttpTask. Этот объект предоставляет ряд методов addXXX, setXXX и tag для построения самой задачи.
Однократное добавление (методы синхронизации и асинхронизации одинаковы):
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();
Параметры пути используются для замены заполнителей в строке 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();
Параметры запроса (параметры 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();
Параметры формы передаются в теле запроса в формате 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();
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();
Загрузка локальных файлов:
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();
Иногда мы классифицируем HTTP-задачи с помощью тегов:
http.async("http://api.demo.com/users")
.tag("MyTag")
.get();
После использования тегов можно отменить все задачи с этим тегом:
http.cancel("MyTag");
Также можно использовать теги для классификации задач в централизованных препроцессорах (см. разделы «Параллельный препроцессор» и «Последовательный препроцессор»).
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()
Чтобы изменить поток выполнения функции обратного вызова, можно настроить функцию обратного вызова. Например, в Android, чтобы все функции обратного вызова выполнялись в потоке пользовательского интерфейса, настройте функцию обратного вызова при создании HTTP
:
HTTP http = HTTP.builder()
.callbackExecutor((Runnable run) -> {
runOnUiThread(run); // выполнение в потоке UI
})
.build();
В отличие от других фреймворков, которые скрывают 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();
Как и перехватчик, можно добавить несколько препроцессоров.
Обычные препроцессоры могут обрабатываться параллельно, но иногда мы хотим, чтобы один препроцессор обрабатывал только одну задачу за раз. Например, если срок действия «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, но стоит отметить, что он не блокирует ни один поток!
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )