Собственная ретрофит-библиотека для сетевых запросов HarmonyOS Next, по умолчанию основанная на @ohos.net.http и @ohos.request, также поддерживает расширение другими http-библиотеками. Может быть настроена на высоком уровне, используя конструктор TypeScript, для быстрого создания HTTP-запросов для HarmonyOS.
ohpm install @lowen/retrofit_next
import { Retrofit } from '@lowen/retrofit_next'
Retrofit.Builder()
.setHost(host: string) // Устанавливает глобальный хост
.setHttpFactory(factory: HttpFactory) // Устанавливает фабрику для создания HTTP-запросов, по умолчанию OhosHttpFactory
.addInterceptor(interceptor: Interceptor) // Добавляет интерцептор, по умолчанию добавляется LogInterceptor
.setHeaders(headers: Map<string, string>) // Устанавливает заголовки
.addHeader(key: string, value: string) // Добавляет заголовок
.setConvertorFactory(factory: ConvertorFactory) // Конвертация данных ответа, напрямую влияет на структуру возвращаемых данных каждого запроса
.setRequestTaskFactory(requestTaskFactory: RequestTaskFactory) // Управление задачами запросов, по умолчанию DefaultRequestTaskFactory
.setConnectTimeout(timeout: number) // Устанавливает время ожидания
.setLoadingFactory(factory: LoadingFactory) // Устанавливает фабрику для создания состояния загрузки
.build()
Интерцепторы запросов, которые можно настроить``` Retrofit.Builder() .addInterceptor(interceptor: Interceptor) // Добавляет интерцептор, по умолчанию добавляется LogInterceptor .build()
### Конвертеры данных
Глобальная обработка данных ответа, унифицированное обработка возвращаемых данных, конфигурация:
Retrofit.Builder() .setConverterFactory(factory: ConvertorFactory) // Конвертация данных ответа, напрямую влияет на структуру возвращаемых данных каждого запроса .build()
- Пример:
import { ConvertorFactory, Response } from '@lowen/retrofit'
// Бизнес-ответ export interface BizResponse { code: number message?: string data?: T }
export interface NetworkError extends BizError {}
export class BizConvertorFactory extends ConvertorFactory {
public convertor(resp: Response): Promise<Object | undefined> {
return new Promise((resolve, reject) => {
// Успешный запрос к интерфейсу
if (resp.isOk) {
// Извлечение бизнес-ответа
let bizResp = resp.result as BizResponse<Object>
if (bizResp.code === 200) {
// Успешное выполнение бизнес-операции, возврат объекта данных запроса, например, User
// async get(@Loading loadingCallback: LoadingCallback): Promise<User> {
// return {} as User
// }
resolve(bizResp.data)
} else {
// Неуспешное выполнение бизнес-операции, выбрасывание исключения
let bizError: BizError = {
code: bizResp.code,
message: bizResp.message,
}
reject(bizError)
}
} else {
// Исключение при запросе к интерфейсу, выбрасывание исключения
let bizError: NetworkError = {
code: resp.code ?? 500,
message: resp.message,
}
reject(bizError)
}
})
}
}
```
```> Примечание: с помощью ConvertorFactory можно настроить возвращаемый тип для методов интерфейса```
## Статус запроса
### Глобальная конфигурация
Глобальная конфигурация статуса запроса, метод конфигурации
```
Retrofit.Builder().setLoadingFactory(new HttpLoadingFactory())
```
- Пример:
```
export class HttpLoadingFactory extends LoadingFactory {
start(url: string): void {
LoadingDialog.showLoading()
}
end(url: string): void {
LoadingDialog.hide()
}
}
```
### BaseNoLoading
Классовый уровень декоратор, локальная конфигурация для всех методов класса, чтобы они не отвечали на глобальную конфигурацию setLoadingFactory()
```
@BaseNoLoading
export class ApiNoLoadService {}
```
### NoLoading
Методовый уровень декоратор, методовый уровень конфигурации для отключения глобальной конфигурации setLoadingFactory()
```
@GET('/get')
@NoLoading
async getLoading(): Promise<User> {
return {} as User
}
```
### Loading
Методовый уровень декоратор, методовый уровень конфигурации для включения глобальной конфигурации setLoadingFactory()
```
@GET('/get')
@Loading
async getLoading(): Promise<User> {
return {} as User
}
```
### Loadable
Уровень параметров декоратор, имеет более высокий приоритет, чем Loading и NoLoading, динамическая конфигурация использования глобального LoadingFactory
```
@GET('/get/user')
async get(@Loadable loadable: boolean): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
### LoadState
Уровень параметров декоратор, имеет самый высокий приоритет, используется вместе с LoadStateCallback для мониторинга начала и завершения запроса, не подвержен влиянию других декораторов Loading
```
@GET('/get/user')
async get(@LoadState loadStateCallback: LoadStateCallback): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```## Конфигурация Host
### 1. Глобальная конфигурация
```
Retrofit.Builder().setHost('https://xxxxx.com') // Установка глобального Host
```
### 2. Конфигурация класса
Имеет более высокий приоритет, чем глобальная конфигурация, применяется к запросам для текущего объекта класса
```
@Host('https://xxxxx.com')
export class ApiService {}
```
## Конфигурация Header
### 1. Глобальная конфигурация
Имеет наименьший приоритет, если Content-type не настроен, по умолчанию будет автоматически добавлен заголовок 'Content-Type', 'application/json'
```
Retrofit.Builder().setHeaders(headers: Map<string, string>) // Установка заголовков
Retrofit.Builder().addHeader(key: string, value: string) // Добавление заголовка
```
### 2. Конфигурация класса
Имеет более высокий приоритет, чем глобальная конфигурация
```
@BaseHeaders({
'Content-type': 'application/json; charset=UTF-8'
})
export class ApiService {}
```
### 3. Конфигурация метода
Приоритет выше конфигурации класса
```
@Headers({
'key1': 'value1',
'key2': 'value2',
})
async get(): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
### 4. Конфигурация параметров
Приоритет выше конфигурации метода
#### Заголовок
```
async get(@Header('key1') key1: string, @Header('key2') key2: string): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
#### HeaderMap
HeaderMap и Map<string, string> объединены
```
async get(@HeaderMap map: Map<string, string>): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
## Обычные запросы
Поддерживает GET, POST, OPTIONS, HEAD, PUT, DELETE, TRACE, CONNECT
### GET
```
@GET('/get/user')
async get(): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```### POST
```
@POST('/post')
async post(@Body body: PostRequest): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
## Загрузка и выгрузка
### Прогресс
Прогресс загрузки и выгрузки, тип параметра должен быть ProgressCallback
```
/**
* @totalByteCount Общее количество байтов, загруженных до текущего момента
* @processByteCount Общее количество байтов, обработанных до текущего момента
*/
export type ProgressCallback = (totalByteCount: number, processByteCount: number) => void;
```
### Загрузка
1. @Body, загрузка не файловых параметров, по умолчанию HttpFactory поддерживает только структуру данных key-value
2. Загрузка файлов, прогресс загрузки настраивается с помощью @Progress и ProgressCallback.
- @Config конфигурация загрузки, тип параметра должен быть UploadConfig
```
export class UploadConfig {
/**
* Расширенная конфигурация, для пользовательских настроек
*/
public extra?: Object
constructor(extra: Object) {
this.extra = extra
}
}
```
#### Часть
1. Загрузка одного файла, применяется к параметрам метода
2. Тип параметра должен быть PartFile, иначе сохраняется
```
/**
* Загрузка, имя файла в заголовке запроса.
*/
export class PartFile {
/**
* Имя файла
*/
filename: string;
/**
* Имя поля формы
*/
name: string;
/**
* Локальный путь к файлу
*/
uri: string;
/**
* Расширение или тип файла
*/
type: string;
}
```
- Пример:
```
@Upload
@POST('/upload')
async upload(@Part file: PartFile, @Progress progressCallback: ProgressCallback): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
> Примечание: Поддерживает upload(@Part file1: PartFile, @Part file2: PartFile) загрузку нескольких файлов
#### PartList1. Множественная загрузка файлов, действует на параметры метода
2. Тип параметра должен быть Array\<PartFile\>
- Пример:
```
@Upload
@POST('/upload')
async upload(@PartList file: PartFile[], @Progress progressCallback: ProgressCallback): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
### Загрузка файлов
Загрузка файлов, можно настроить URL загрузки через GET или POST (для HarmonyOS GET и POST не будут работать), а также можно задать URL загрузки через @Url.
- @Config настройки загрузки, тип параметра должен быть DownloadConfig
```
export class DownloadConfig {
/**
* Путь к целевому файлу
*/
public targetPath: string
/**
* Расширенные настройки, для пользовательских нужд
*/
public extra?: Object
constructor(targetPath: string, extra?: Object) {
this.targetPath = targetPath
this.extra = extra
}
}
```
- Пример:
```
@Download
@GET('/get/user/info')
async download(@Config config: DownloadConfig, @Progress progressCallback: ProgressCallback): Promise<BizResponse<void>> {
return {} as BizResponse<void>
}
```
## Параметры метода
### Path
1. Заменяет указанные параметры в URL путях.
2. Преобразует значение в строку с помощью toString() и URL-кодирования.
3. Значение параметра, определенного с помощью этого аннотирования, не может быть пустым. По умолчанию используется URL-кодирование.
```
@GET('/get/{p1}/info')
async get(@Path('p1') p1: string): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
> Пример: Если параметр p1='user', полный путь запроса будет: /get/user/info
### Query
1. Используется для добавления параметров запроса (Query = key-value после '?' в URL).
2. Значение параметра преобразуется в строку с помощью toString() и URL-кодируется.```
@GET('/get/user/info')
async get(@Query('p1') p1: string, @Query('p2') p2: string): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
> Пример: get('v1', 'v2'), путь запроса будет: /get/user/info?p1=v1&p2=v2
### QueryMap
1. Добавляет параметры запроса в виде карты (Query = key-value после '?' в URL).
2. Значение параметра преобразуется в строку с помощью toString() и URL-кодируется.
3. Тип параметра должен быть Map<string, Object>, в противном случае будет ошибка.
```
@GET('/get/user/info')
async get(@QueryMap querys: Map<string, Object>,): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
> Пример: let params: Map<string, string> = new Map();<br/>
> params.set('p1', 'v1');<br/>
> params.set('p2', 'v2');<br/>
> get(params);<br/>
>
> Путь запроса будет: /get/user/info?p1=v1&p2=v2
### URL
Просто передайте переменную URL запроса, чтобы установить URL-адрес запроса и заменить его в существующей конфигурации.
```typescript
@Download
async download(@Url url: string, @Config config: DownloadConfig,
@Progress progressCallback: ProgressCallback): Promise<BizResponse<void>> {
return {} as BizResponse<void>
}
```
### FormUrlEncoded
FormUrlEncoded не может использоваться для GET-запросов, не следует использовать его произвольно.
1. Используется для аннотации полей @Field и @FieldMap.
Эта аннотация указывает, что тело запроса будет использовать форму URL-кодирования. Поля должны быть объявлены как параметры и аннотированы @Field или @FieldMap. Запросы, аннотированные FormUrlEncoded, будут иметь MIME-тип "application/x-www-form-urlencoded".
#### Field
Поля формы, отправляемые при POST-запросе, совместно с @FormUrlEncoded аннотацией.
``typescript
@FormUrlEncoded
@POST("/post")
async post(@Field("time") long time): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```@FormUrlEncoded
@POST("/post")
async post(@Field("name") String... names): Promise<BizResponse<User>> {
return {} as BizResponse<User>
}
```
#### FieldMap
Поля формы, совместно с `Field` и `FormUrlEncoded`; принимают тип `Map`, для нестринговых типов будет вызван метод `toString()`.
``typescript
@FormUrlEncoded
@POST("/post")
Call<List<Repo>> things(@FieldMap Map<String, String> params);
return {} as BizResponse<User>
}
```
## Пользовательские расширения
### Расширитель декораторов
`BaseExtra` (декоратор уровня класса), `FixedExtra` (декоратор уровня метода), `Extra` (декоратор уровня параметра), пользовательские расширения доступны через `RequestTask.extra`, параметры расширения могут быть использованы в `Interceptor` и пользовательском `RequestTaskFactory`, `HttpFactory`.
- Пример
```typescript
@BaseExtra('BaseExtra')
export class ApiService {
@FixedExtra('FixedExtra')
async getLoading(@Extra extra: string): Promise<User> {
return {} as User
}
}
```
Пользовательский HTTP-запросный фабрикатор
```typescript
/**
* Фабрика построения HTTP-запросов для HarmonyOS
*/
export class CustomHttpFactory extends HttpFactory {
/**
* HTTP-запрос
* @param task Задача запроса
* @returns
*/
public httpRequest(task: RequestTask): Promise<HttpResponse> {
let extra: ExtraObject | undefined = task.extra
}
}
```
Пользовательский интерцептор
```typescript
export class LogInterceptor extends Interceptor {
public intercept(chain: Chain): Promise<Response> {
let extra: ExtraObject | undefined = chain.request.extra
}
}
```
### Настройка управления задачами запросов
Переопределите `RequestTaskFactory`, используя по умолчанию [DefaultRequestTaskFactory](https://gitee.com/lowen/retrofit_next/blob/master/library/src/main/ets/factory/DefaultRequestTaskFactory.ets)### Настройка сетевых запросов
Переопределите `HttpFactory`, используя по умолчанию [OhosHttpFactory](https://gitee.com/lowen/retrofit_next/blob/master/library/src/main/ets/factory/OhosHttpFactory.ets).
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )