- Retrofit
- Задача первая. POJO
- Задача вторая. Интерфейс
- Аннотации
- @Query
- @Headers
- @Multipart
- @FormUrlEncoded
- Задача третья. Retrofit
- Перехватчики (Interceptors)
- HttpLoggingInterceptor
- RxJava
- Retrofit
- A type-safe HTTP client for Android and Java
- Introduction
- API Declaration
- Request Method
- URL Manipulation
- Request Body
- Form Encoded and Multipart
- Header Manipulation
- Synchronous vs. Asynchronous
- Retrofit Configuration
- Converters
- Custom Converters
- Download
- Maven
- Gradle
- R8 / ProGuard
- Contributing
Retrofit
Многие сайты имеют собственные API для удобного доступа к своим данным. На данный момент самый распространённый вариант — это JSON. Также могут встречаться данные в виде XML и других форматов.
Библиотека Retrofit упрощает взаимодействие с REST API сайта, беря на себя часть рутинной работы.
Авторами библиотеки Retrofit являются разработчики из компании «Square», которые написали множество полезных библиотек, например, Picasso, Okhttp, Otto.
Библиотекой удобно пользоваться для запроса к различным веб-сервисам с командами GET, POST, PUT, DELETE. Может работать в асинхронном режиме, что избавляет от лишнего кода.
В основном вам придётся работать с методами GET и POST. Если вы будет создавать собственный API, то будете использовать и другие команды.
В Retrofit 2.x автоматически подключается библиотека OkHttp и её не нужно прописывать отдельно.
Библиотека может работать с GSON и XML, используя специальные конвертеры, которые следует указать отдельно.
Затем в коде конвертер добавляется с помощью метода addConverterFactory().
Список готовых конвертеров:
- Gson: com.squareup.retrofit2:converter-gson
- Jackson: com.squareup.retrofit2:converter-jackson
- Moshi: com.squareup.retrofit2:converter-moshi
- Protobuf: com.squareup.retrofit2:converter-protobuf
- Wire: com.squareup.retrofit2:converter-wire
- Simple XML: com.squareup.retrofit2:converter-simplexml
- Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
Также вы можете создать свой собственный конвертер, реализовав интерфейс на основе абстрактного класса Converter.Factory.
Можно подключить несколько конвертеров (порядок важен).
Если вы хотите изменить формат какого-нибудь JSON-объекта, то это можно сделать с помощью GsonConverterFactory.create():
Базовый URL всегда заканчивается слешем /. Задаётся в методе baseUrl().
Можно указать полный URL в запросе, тогда базовый URL будет проигнорирован:
Для работы с Retrofit понадобятся три класса.
- POJO (Plain Old Java Object) или Model Class — json-ответ от сервера нужно реализовать как модель
- Retrofit — класс для обработки результатов. Ему нужно указать базовый адрес в методе baseUrl()
- Interface — интерфейс для управления адресом, используя команды GET, POST и т.д.
Работу с Retrofit можно разбить на отдельные задачи.
Задача первая. POJO
Задача первая — посмотреть на структуру ответа сайта в виде JSON (или других форматов) и создать на его основе Java-класс в виде POJO.
POJO удобнее создавать с помощью готовых веб-сервисов в автоматическом режиме. Либо можете самостоятельно создать класс, если структура не слишком сложная.
В классе часто используются аннотации. Иногда они необходимы, иногда их можно пропустить. В некоторых случаях аннотации помогают избежать ошибок. Список аннотаций зависит от типа используемого конвертера, их список можно посмотреть в соответствующей документации.
Задача вторая. Интерфейс
Задача вторая — создать интерфейс и указать имя метода. Добавить необходимые параметры, если они требуются.
В интерфейсе задаются команды-запросы для сервера. Команда комбинируется с базовым адресом сайта (baseUrl()) и получается полный путь к странице. Код может быть простым и сложным. Можно посмотреть примеры в документации.
Запросы размещаются в обобщённом классе Call с указанием желаемого типа.
В большинстве случаев вы будете возвращать объект Call с нужным типом, например, Call . Если вас не интересует тип ответа, то можете указать Call .
Здесь также используются аннотации, но уже от самой библиотеки.
С помощью аннотации указываются веб-команды, а затем Java-метод. Для динамических параметров используются фигурные скобки (users/
В самой аннотации используется метод, используемый на сервере, а ниже вы можете указать свой вариант (полезно для соответствия стилю вашего кода.
Аннотации
Аннотация | Описание |
---|---|
@GET() | GET-запрос для базового адреса. Также можно указать параметры в скобках |
@POST() | POST-запрос для базового адреса. Также можно указать параметры в скобках |
@Path | Переменная для замещения конечной точки, например, username подставится в в адресе конечной точки |
@Query | Задаёт имя ключа запроса со значением параметра |
@Body | Используется в POST-вызовах (из Java-объекта в JSON-строку) |
@Header | Задаёт заголовок со значением параметра |
@Headers | Задаёт все заголовки вместе |
@Multipart | Используется при загрузке файлов или изображений |
@FormUrlEncoded | Используется при использовании пары «имя/значение» в POST-запросах |
@FieldMap | Используется при использовании пары «имя/значение» в POST-запросах |
@Url | Для поддержки динамических адресов |
@Query
Аннотация @Query полезна при запросах с параметрами. Допустим, у сайте есть дополнительный параметр к запросу, который выводит список элементов в отсортированном виде: http://example.com/api/v1/products/cats?sort=desc. Это несложный пример и мы можем поместить запрос с параметром в интерфейс без изменений.
Если не требуется управлять сортировкой, то её можно оставить в коде и она будет применяться по умолчанию. Но в нашем запросе есть ещё один параметр, который отвечает за категорию котов (домашние, уличные, породистые), которая может меняться в зависимости от логики приложения. Этот параметр можно снабдить аннотацией и программно управлять в коде.
Сортировку мы оставляем как есть, а категорию перенесли в параметры метода под именем categoryId, снабдив аннотацией, с которой параметр будет обращаться на сервер в составе запроса.
Запрос получится в виде http://example.com/api/v1/products/cats?sort=desc&category=5.
В одном методе можно указать несколько Query-параметров.
Запрос может иметь изменяемые части пути. Посмотрите на один из примеров запроса для GitHub: /users/:username. Вместо :username следует подставлять конкретные имена пользователей (https://api.github.com/users/alexanderklimov). В таких случаях используют фигурные скобки в запросе, в самоме методе через аннотацию @Path указывается имя, которое будет подставляться в путь.
@Headers
Пример аннотации @Headers, которая позволяет указать все заголовки вместе.
@Multipart
Пример аннотации @Multipart при загрузке файлов или картинок:
@FormUrlEncoded
Пример использования аннотации @FormUrlEncoded:
Пример аннотации @Url:
Задача третья. Retrofit
Для синхронного запроса используйте метод Call.execute(), для асинхронного — метод Call.enqueue().
Объект для запроса к серверу создаётся в простейшем случае следующим образом
В итоге мы получили объект Retrofit, содержащий базовый URL и способность преобразовывать JSON-данные с помощью указанного конвертера Gson.
Далее в его методе create() указываем наш класс интерфейса с запросами к сайту.
После этого мы получаем объект Call и вызываем метод enqueue() (для асинхронного вызова) и создаём для него Callback. Запрос будет выполнен в отдельном потоке, а результат придет в Callback в main-потоке.
В результате библиотека Retrofit сделает запрос, получит ответ и производёт разбор ответа, раскладывая по полочкам данные. Вам остаётся только вызывать нужные методы класса-модели для извлечения данных.
Основная часть работы происходит в onResponse(), ошибки выводятся в onFailure() (неправильный адрес сервера, некорректные формат данных, неправильный формат класса-модели и т.п). HTTP-коды сервера (например, 404) не относятся к ошибкам.
Метод onResponse() вызывается всегда, даже если запрос был неуспешным. Класс Response имеет удобный метод isSuccessful() для успешной обработки запроса (коды 200хх). В ошибочных ситуациях вы можете обработать ошибку в методе errorBody() класса ResponseBody.
Другие полезные методы Response.
- code() — HTTP-код ответа
- body() — сам ответ в виде строки, без сериализации
- headers() — HTTP-заголовки
- message() — HTTP-статус (или null)
- raw() — сырой HTTP-ответ
Можно написать такую конструкцию.
Для отмены запроса используется метод Call.cancel().
Перехватчики (Interceptors)
В библиотеку можно внедрить перехватчики для изменения заголовков при помощи класса Interceptor из OkHttp. Сначала следует создать объект перехватчика и передать его в OkHttp, который в свою очередь следует явно подключить в Retrofit.Builder через метод client().
Поддержка перехватчиков/interceptors для обработки заголовков запросов, например, для работы с токенами авторизации в заголовке Authorization.
HttpLoggingInterceptor
Библиотека HttpLoggingInterceptor является частью OkHttp, но поставляется отдельно от неё. Перехватчик следует использовать в том случае, когда вам действительно нужно изучать логи ответов сервера. По сути библиотека является сетевым аналогом привычного LogCat.
Подключаем перехватчик к веб-клиенту. Добавляйте его после других перехватчиков, чтобы ловить все сообщения. Существует несколько уровней перехвата данных: NONE, BASIC, HEADERS, BODY. Последний вариант самый информативный, пользуйтесь им осторожно. При больших потоках данных информация забьёт весь экран. Используйте промежуточные варианты.
RxJava
Сами разработчики библиотеки очень любят реактивное программирование и приложили многие усилия для интеграции с библиотекой RxJava.
Источник
Retrofit
A type-safe HTTP client for Android and Java
Introduction
Retrofit turns your HTTP API into a Java interface.
The Retrofit class generates an implementation of the GitHubService interface.
Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.
Use annotations to describe the HTTP request:
- URL parameter replacement and query parameter support
- Object conversion to request body (e.g., JSON, protocol buffers)
- Multipart request body and file upload
API Declaration
Annotations on the interface methods and its parameters indicate how a request will be handled.
Request Method
Every method must have an HTTP annotation that provides the request method and relative URL. There are eight built-in annotations: HTTP , GET , POST , PUT , PATCH , DELETE , OPTIONS and HEAD . The relative URL of the resource is specified in the annotation.
You can also specify query parameters in the URL.
URL Manipulation
A request URL can be updated dynamically using replacement blocks and parameters on the method. A replacement block is an alphanumeric string surrounded by < and >. A corresponding parameter must be annotated with @Path using the same string.
Query parameters can also be added.
For complex query parameter combinations a Map can be used.
Request Body
An object can be specified for use as an HTTP request body with the @Body annotation.
The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.
Form Encoded and Multipart
Methods can also be declared to send form-encoded and multipart data.
Form-encoded data is sent when @FormUrlEncoded is present on the method. Each key-value pair is annotated with @Field containing the name and the object providing the value.
Multipart requests are used when @Multipart is present on the method. Parts are declared using the @Part annotation.
Multipart parts use one of Retrofit ‘s converters or they can implement RequestBody to handle their own serialization.
Header Manipulation
You can set static headers for a method using the @Headers annotation.
Note that headers do not overwrite each other. All headers with the same name will be included in the request.
A request Header can be updated dynamically using the @Header annotation. A corresponding parameter must be provided to the @Header . If the value is null, the header will be omitted. Otherwise, toString will be called on the value, and the result used.
Similar to query parameters, for complex header combinations, a Map can be used.
Headers that need to be added to every request can be specified using an OkHttp interceptor.
Synchronous vs. Asynchronous
Call instances can be executed either synchronously or asynchronously. Each instance can only be used once, but calling clone() will create a new instance that can be used.
On Android, callbacks will be executed on the main thread. On the JVM, callbacks will happen on the same thread that executed the HTTP request.
Retrofit Configuration
Retrofit is the class through which your API interfaces are turned into callable objects. By default, Retrofit will give you sane defaults for your platform but it allows for customization.
Converters
By default, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type and it can only accept its RequestBody type for @Body .
Converters can be added to support other types. Six sibling modules adapt popular serialization libraries for your convenience.
- Gson: com.squareup.retrofit2:converter-gson
- Jackson: com.squareup.retrofit2:converter-jackson
- Moshi: com.squareup.retrofit2:converter-moshi
- Protobuf: com.squareup.retrofit2:converter-protobuf
- Wire: com.squareup.retrofit2:converter-wire
- Simple XML: com.squareup.retrofit2:converter-simplexml
- JAXB: com.squareup.retrofit2:converter-jaxb
- Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
Here’s an example of using the GsonConverterFactory class to generate an implementation of the GitHubService interface which uses Gson for its deserialization.
Custom Converters
If you need to communicate with an API that uses a content-format that Retrofit does not support out of the box (e.g. YAML, txt, custom format) or you wish to use a different library to implement an existing format, you can easily create your own converter. Create a class that extends the Converter.Factory class and pass in an instance when building your adapter.
Download
The source code to the Retrofit, its samples, and this website is available on GitHub.
Maven
Gradle
Retrofit requires at minimum Java 8+ or Android API 21+.
R8 / ProGuard
If you are using R8 the shrinking and obfuscation rules are included automatically.
ProGuard users must manually add the options from retrofit2.pro.
You might also need rules for OkHttp and Okio which are dependencies of this library.
Contributing
If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request.
When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. Please also make sure your code compiles by running ./gradlew build (or gradlew.bat build for Windows).
Before your code can be accepted into the project you must also sign the Individual Contributor License Agreement (CLA).
Источник