Retrofit что это
Перейти к содержимому

Retrofit что это

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 понадобятся три класса.

  1. POJO (Plain Old Java Object) или Model Class — json-ответ от сервера нужно реализовать как модель
  2. Retrofit — класс для обработки результатов. Ему нужно указать базовый адрес в методе baseUrl()
  3. Interface — интерфейс для управления адресом, используя команды GET, POST и т.д.

Работу с Retrofit можно разбить на отдельные задачи.

Задача первая. POJO

Задача первая — посмотреть на структуру ответа сайта в виде JSON (или других форматов) и создать на его основе Java-класс в виде POJO.

POJO удобнее создавать с помощью готовых веб-сервисов в автоматическом режиме. Либо можете самостоятельно создать класс, если структура не слишком сложная.

В классе часто используются аннотации. Иногда они необходимы, иногда их можно пропустить. В некоторых случаях аннотации помогают избежать ошибок. Список аннотаций зависит от типа используемого конвертера, их список можно посмотреть в соответствующей документации.

Задача вторая. Интерфейс

Задача вторая — создать интерфейс и указать имя метода. Добавить необходимые параметры, если они требуются.

В интерфейсе задаются команды-запросы для сервера. Команда комбинируется с базовым адресом сайта (baseUrl()) и получается полный путь к странице. Код может быть простым и сложным. Можно посмотреть примеры в документации.

Запросы размещаются в обобщённом классе Call с указанием желаемого типа.

В большинстве случаев вы будете возвращать объект Call<T> с нужным типом, например, Call<User>. Если вас не интересует тип ответа, то можете указать Call<Response>.

Здесь также используются аннотации, но уже от самой библиотеки.

С помощью аннотации указываются веб-команды, а затем Java-метод. Для динамических параметров используются фигурные скобки (users//repos), в которые подставляются нужные значения.

В самой аннотации используется метод, используемый на сервере, а ниже вы можете указать свой вариант (полезно для соответствия стилю вашего кода.

Аннотации

Аннотация Описание
@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 — библиотека для работы с REST API

Продолжаем разбирать библиотеки от Square. Сегодня мы познакомимся поближе с замечательной библиотекой Retrofit.

Внимание: данная статья немного устарела в связи с выходом библиотеки Retrofit 2, но все же мы советуем ознакомиться с содержанием данного поста, для понимания базовых принципов работы библиотеки. Новый обзор можно почитать здесь.

Замечательна она тем, что:

1) Больше не нужно выводить запросы к API в отдельный поток в коде — Retrofit это сделает за нас.
2) Значительно сокращает длину кода и, соответсвенно, ускоряет разработку
3) Динамически строит запросы
4) Автоматически конвертирует JSON в объекты (используется библиотека Gson)
5) Обрабатывает ошибки
6) Умеет передавать файлы

Вся логика работы библиотека завязана на аннотациях. Благодаря ним можно создавать динамические запросы на сервер.

Описание API

Описание запросов к серверу происходит в интерфейсе. Над каждым методом должна стоять аннотация, с помощью которой Retrofit «узнает», какого типа запрос.
Также с помощью аннотаций можно указывать параметры запроса.

Вот так, например, выглядит описание GET-запроса:

Как видите, нам не нужно указывать адрес сайта, который отправляется запрос, нужно лишь указать расположение самого PHP файла на сервере (позже объясню почему). В классе Response содержится информация о статусе запроса и ответ от сервера.

А вот так выглядит POST-запрос:

Можно изменять путь к файлу динамически:

Retrofit заменит слово «» на, то которое вы передали методу. Сам аргумент должен быть аннотирован словом Path и в скобках нужно указать ключевое слово.

Параметры запроса

Тут тоже нет ничего сложного:

Для того, чтобы задать запросу параметры используется аннотация @Query. Слово указанное в скобках рядом с аннотацией будет ключом, а аннотированый аргумент значением.

Синхронные и асинхронные запросы

У вас есть два способа отправки запроса: синхронный и асинхронный. Для синхронной отправки запроса нужно вынести его в отдельный поток. Пример синхронной отправки запроса:

В ассинхронном запросе метод ничего не возвращает (void), но обязательно должен принимать на вход объект интерфейса Callback<T>. В качестве параметра интерфейса нужно передать тип возвращаемого объекта. Вот пример ассинхронного запроса:

Превращаем интерфейс в API

После того, как мы описали все запросы к серверу в интерфейсе нужно передать этот интерфейс специальному классу, который обработает этот интерфейс и сгенерирует код запросов.

Выше я писал, что при описании запроса адрес сайта указывать не нужно, достаточно указать его в методе setEndpoint и Retrofit сам подставит его в начале адреса запроса

Используем API

Пример асинхронного GET-запроса:

Описываем запросы к API

Создаем интерфейс для работы с API

Пример синхронного POST-запроса:

Описываем запросы к API

Создаем интерфейс для работы с API

Запрос с большим количеством полей

Если вам нужно послать запрос с большим количеством параметров, то будет лучше использовать Map<String, String> и добавлять параметры туда.

Получаем строку из Response

Данные полученные от сервера класс Response выдает в виде InputStream, чтобы пользователь сам преобразовал ответ в нужный ему тип данных. Здесь мы рассмотрим пример перевода InputStream в строку:

Multipart-запросы

Описание Multipart-запроса похоже на описание POST-запроса, только вместо @FormUrlEncoded мы пишем @Multipart. На вход подается объект класса TypedFile с аннотацией @Part, указывающей на имя поля.

TypedFile — тот же класс File, только с указанием MIME-типа.

Конвертируем ответ в объекты

В интерфейсе в качестве возвращаемого класса ставим класс Book:

Вызываем метод getBook:

Для конвертирования JSON в объекты Retrofit использует библиотеку Gson. Она автоматически найдет поля в классе и присвоит им соотвествующий текст. Подробнее про Gson вы можете почитать здесь.

Работа с заголовками

Управление заголовками происходит с помощью аннотаций @Header и @Headers.

Простейший пример использования аннотации @Headers:

Также можно указывать несколько заголовков:

Также заголовок можно менять динамически используя аннотацию @Header.

Слово «Authorization» будет использовано в качестве имени заголовка, а переменная authorization как значение. Если переменная authorization равна null, то заголовок не добавится.

Если какой-нибудь заголовок нужно добавлять в каждый запрос (например User-Agent), то это можно сделать с помощью интерфейса RequestInterceptor. В методе intercept(RequestFacade) мы добавляем нужные нам заголовки.

Далее вызываем метод setRequestInterceptor у RestAdapter’а и указываем в качестве аргумента созданный нами RequestInterceptor.

Внимание!

Если у вас возникает ошибка

то, скорее всего, вы не подключили библиотеку GSON от Google или подключили ее неправильно.

Using Retrofit 2.x as REST client — Tutorial

Retrofit is a REST Client for Java and Android allowing to retrieve and upload JSON (or other structured data) via a REST based You can configure which converters are used for the data serialization, example GSON for JSON.

1.2. Using Retrofit

To work with Retrofit you basically need the following three classes:

Model class which is used as a JSON model

Interfaces that define the possible HTTP operations

Retrofit.Builder class — Instance which uses the interface and the Builder API to allow defining the URL end point for the HTTP operations.

Every method of an interface represents one possible API call. It must have a HTTP annotation ( GET , POST , etc.) to specify the request type and the relative URL. The return value wraps the response in a Call object with the type of the expected result.

You can use replacement blocks and query parameters to adjust the URL. A replacement block is added to the relative URL with <> . With the help of the @Path annotation on the method parameter, the value of that parameter is bound to the specific replacement block.

Query parameters are added with the @Query annotation on a method parameter. They are automatically added at the end of the URL.

The @Body annotation on a method parameter tells Retrofit to use the object as the request body for the call.

2. Prerequisitions

The following examples are using the Eclipse IDE together with the Maven or the Gradle build system. See the following links to learn about the usage of Maven or Gradle in the Eclipse IDE

Other tools like Visual Studio Code or IntelliJ allow to do the same, so you should be able to use your favorite tool.

3. Exercise: A first retrofit client

In this exercise you will create a standalone REST client. The responses are generated by a mock server.

3.1. Project creation and setup

Create a new Gradle project called com.vogella.retrofitgerrit . Add a new package to src/main/java with the name com.vogella.retrofitgerrit .

Add the following dependencies to your build.gradle file.

3.2. Define the API and the Retrofit adapter

In the JSON reply from Gerrit we are only interested in the subject of the changes. Therefore create the following data class in the previously added default package.

Define the REST API for Retrofit via the following interface.

Create the following controller class. This class creates the Retrofit client, calls the Gerrit API and handles the result (prints the result of the call to the console).

Create a class with a main -method to start the controller.

4. Retrofit converters and adapters

4.1. Retrofit Converters

Retrofit can be configured to use a specific converter. This converter handles the data (de)serialization. Several converters are already available for various serialization formats.

To convert to and from JSON:

To convert to and from Protocol Buffers:

To convert to and from XML:

Simple XML: com.squareup.retrofit:converter-simplexml

Besides the listed converters, you can also create custom converters to process other protocols by subclassing the Converter.Factory class.

4.2. Retrofit Adapters

Retrofit can also be extended by adapters to get involved with other libraries like RxJava 2.x, Java 8 and Guava.

An overview for available adapters can be found on Github square/retrofit/retrofit-adapters/.

For example the RxJava 2.x adapter can be obtained by using Gradle:

or using Apache Maven:

In order to add an adapter the retrofit2.Retrofit.Builder.addCallAdapterFactory(Factory) method has to be used.

With this adapter being applied the Retrofit interfaces are able to return RxJava 2.x types, e.g., Observable, Flowable or Single and so on.

5. Retrofit authentication

Retrofit supports API calls that need authentication. Authentication can be done by using a username and a password (Http Basic authentication) or an API token.

There are two ways, how you can handle the authentication. The first method would be to manipulate the header for the request with the help of annotations. Another possibility would be to use an OkHttp interceptor for that.

5.1. Authentication with annotations

Assume, that you want to request your user details, which requires you to authenticate. You can do this by adding a new parameter to your API definition, like the following:

With the help of the @Header(«Authorization») annotation you tell Retrofit to add the Authorization field to the request header with the value you provide for credentials .

To generate Basic authentication credentials, you can use OkHttps Credentials class with its basic(String, String) method. The method takes the username and the password and returns the authentication credential for the Basic scheme.

If you want to use an API token and no Basic authentication, just call the getUserDetails(String) method with your token instead.

5.2. Authentication with OkHttp interceptors

The above method only adds the credentials, if you request your user details. If you have more calls that require you to authenticate, you can use an interceptor for this. An interceptor is used to modify each request before it is performed and alters the request header. The advantage is, that you don’t have to add @Header(«Authorization») to each API method definition.

To add an interceptor, you have to use the okhttp3.OkHttpClient.Builder.addInterceptor(Interceptor) method on the OkHttp Builder.

The created OkHttp client has to be added to your Retrofit client with the retrofit2.Retrofit.Builder.client(OkHttpClient) method.

You may again noticed the usage of the Credentials class for Basic authentication. Again, if you want to use a API token, just use the token instead.

6. Exercise: Using Retrofit to query Gerrit in Java

The following section describes how to create a minimal Java application which uses Retrofit to query the subjects of open changes from the Gerrit API. The results are printed on the console.

6.1. Project creation and setup

This exercise assumes that you are familiar with Gradle and Buildship for Eclipse.

Create a new Gradle project with the name com.vogella.java.retrofitgerrit . Add a new package to src/main/java with the name com.vogella.java.retrofitgerrit .

Add the following dependencies to your build.gradle file.

6.2. Define the API and the Retrofit adapter

In the JSON reply from Gerrit we are only interested in the subject of the changes. Therefore create the following data classe in the previously added default package.

Define the REST API for Retrofit via the following interface.

Create the following controller class. This class creates the Retrofit client, calls the Gerrit API and handles the result (prints the result of the call on the console).

Create a class with a main-method to start the controller.

7. Exercise: Using Retrofit to convert XML response from an RSS feed

This section describes the usage of Retrofit to convert a XML response with the help of the SimpleXMLConverter .

A minimal Java application is created that requests the Vogella RSS feed (http://vogella.com/article.rss) and prints out the channel title and the titles and the links of the articles.

7.1. Project creation and setup

This exercise assumes that you are familiar with Gradle and Buildship for Eclipse.

Create a new Gradle project with the name com.vogella.java.retrofitxml . Add a new package to src/main/java with the name com.vogella.java.retrofitxml .

Add the following dependencies to your build.gradle file.

7.2. Define the XML mapping

An RSS feed looks like the following:

Besides the XML header this file consists of various XML elements. The rss-element contains a channel-element which again contains other elements (i.e. title, description, pubDate) and several item-elements (the articles).

Create the following two data classes named RSSFeed and Article .

The Article class represents one single article and only stores the title and the link to it. These are the only fields we are interested in.

With the @Root annotation a class is marked to be (de)serialized. Optionally, you can provide a name in the @Root annotation that represents the name of the XML element. If no name is provided, the class name is used as the XML element name. Because the class name (RSSFeed) is different to the XML element name (rss), you have to provide the name.

With strict set to false , strict parsing is disabled. This tells the parser to not fail and throw an exception, if a XML element or attribute is found for which no mapping is provided. As the rss-element has the version attribute which is not bound to a field, the application would crash, if it is not set to false.

With the help of the @Element annotation, an XML element is represented. Optionally, you can provide a name for the XML element that is represented by that field. If no name is provided, the fields name is used.

The field articleList is annotated with @ElementList . That indicates, that this field is used to store a Collection (in our case: List<Article> ) of XML elements with the same name. With inline set to true it is determined that the elements of the Collection are inlined. That means, that they have no enclosing element and are listed one after another within the XML response.

With the @Path annotation you can provide a path to an XML element inside the XML tree. This is helpful, if you don’t want to model the complete XML tree with Java objects. For the title of the channel and the several item-elements, we can directly point to the specific elements within the channel-element.

7.3. Define the API and the Retrofit adapter

Define the REST API for Retrofit via the following interface.

Create the following controller class. This class creates the Retrofit client, calls the Vogella API and handles the result.

The last step is to create a class with a main -method to start the controller.

8. Using retrofit for querying the restful StackOverflow API

StackOverflow is a popular side for programming related questions. It also provides a REST API which is well documented on the Stackoverflow API page.

In this exercise you use the Retrofit REST library to query StackOverflow for questions based on tags The implementation also allows to the answers to posted questions.s

We use the following query URL in our example. Open this URL in the browser and have a look at the response.

8.1. Project creation and setup

Create a new Maven project called com.vogella.stackoverflow.maven .

Add the following dependencies to pom file.

8.2. Create data model

Create the following two data classes which are used to store the response data from Stackoverflow.

8.3. Define the API and the Retrofit adapter

The Stackoverflow API wraps replies for questions or answers in a JSON object with the name items . To handle this, create the following data class named ListWrapper . This is needed to handled the Stackoverflow items wrapper. This class accepts a type parameter and simply wraps a list of objects of that type.

Define the REST API for Retrofit via the following interface.

8.4. Test implementation

Write the following test class to check the call. This is a standalone test

9. Exercise: Using Retrofit to access GitHub API in Android

This exercise describes how to list all GitHub repositories for a user in an Android application using Retrofit. You can select a repository from a drop-down field and list the issues that are assigned to the user for the selected repository.

You can then select an issue from an additional drop-down field and post a comment on it. A DialogFragment is used to enter the credentials for authentication.

Make sure, that you have a Github account, as it is a requirement for this tutorial. As Retrofit is used in conjunction with RxJava2 during this tutorial, make sure that you also check out the RxJava2 Tutorial.

9.1. Project setup

Create an Android application with the name Retrofit Github . Use com.vogella.android.retrofitgithub as the top level package name and use the empty template. Ensure to select the Backwards Compatibility flag in the wizard.

To use Retrofit and RxJava2 CallAdapter, add the following dependencies to your build.gradle file

Add the permission to access the Internet to your manifest file.

9.2. Define the API

Create the following two data classes called GithubIssue and GithubRepo .

From the repositories, only the name and the url of the repository is displayed in the drop-down field. Also add owner to the data class as the owner name is mandatory for requesting the issues later.

We only show the id and the title of the issue in the drop-down field, so create a field for each of them. Furthermore, the response from Github contains the URL to post the comment to, which is stored in the field comments_url. To later post a new comment to the Github API, add a field called comment. The Github API specifies that the contents of a comment has to be bound to a field named body in the JSON request. As Retrofit (de)serializes all fields based on their name and as we don’t want to use body as the field name in our GithubIssue class, we use the @SerializedName annotation. With the help of this annotation, we can change the name a field is (de)serialized to in the JSON.

Unfortunately the GithubRepo class is not enough to query all needed repository information. As you can see here, the owner of a repository is a separate JSON object within the repository response and therefore it normally needs a corresponding Java class for (de)serialization. Fortunately Retrofit gives yu the possibility to add an own typed JSONDeserializer to control the deserialization for a specific type. Every time an object of the specific type has to be deserialized, this custom Deserializer is used.

To do so, add the following class called GithubRepoDeserialzer.

Define the REST API for Retrofit via the following interface:

You might wonder about the @Url annotation. With the help of this annotation, we can provide the URL for this request. This allows us to change the URL for each request dynamically. We need this for the comments_url field of the GithubIssue class.

The @Path annotation binds the parameter value to the corresponding variable (curly brackets) in the request URL. This is needed to specify the owner and the repository name for which the issues should be requested

Используем Retrofit 2 в Android-приложении

Retrofit — это известная среди Android-разработчиков библиотека для сетевого взаимодействия, некоторые даже считают её в каком-то роде стандартом. Причин для такой популярности масса: библиотека отлично поддерживает REST API, легко тестируется и настраивается, а запросы по сети с её помощью выполняются совсем просто. В этой статье я покажу вам, как настроить и использовать Retrofit, чтобы реализовать работу с сетью в вашем приложении.

Настройка Retrofit

Добавьте следующую зависимость в файл build.gradle :

Мы будем использовать Gson для преобразования JSON в POJO. Retrofit предоставляет зависимость, которая автоматически конвертирует JSON в POJO. Для этого добавьте ещё одну зависимость в файл build.gradle :

Если в вашем приложении ещё не разрешена работа с сетью, то обязательно добавьте соответствующую строку в файл AndroidManifest :

После того, как зависимости добавлены, нам необходимо написать код для настройки библиотеки Retrofit.

Создайте класс с именем NetworkService :

Этот класс должен быть singleton-объектом, поэтому объявите статическую переменную и функцию, которая создаёт и возвращает переменную того же типа, что и класс. Если вы не знаете, как работает данный паттерн, то ознакомьтесь с этой статьёй, в которой есть примеры реализации на языке Java.

Для тестирования мы используем JSONPlaceholder, который предоставляет фейковый онлайн REST API для разработчиков:

Теперь мы объявим и инициализируем Retrofit в конструкторе NetworkService :

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

Добавление конечных точек

Создайте интерфейс с именем JSONPlaceHolderApi :

На сайте JSONPlaceHolder URL /posts/id — это конечная точка, которая возвращает сообщение с соответствующим идентификатором. Данная конечная точка принимает GET-запрос и возвращает данные в формате JSON в следующем виде:

Сначала мы создадим соответствующий POJO для JSON-ответа:

Как вы видите, это простой POJO-класс. Переменные мы аннотировали с помощью @SerializedName() , передав туда имя. Эти имена фактически являются ключами в возвращаемых из API JSON-данных, поэтому вы можете как угодно изменять имя переменной, но убедитесь, что имя, переданное в аннотацию @SerializedName() , точно присутствует в JSON.

В интерфейсе, созданном выше, определите конечные точки с требуемыми параметрами:

Поскольку мы отправляем GET-запрос, нам нужно применить к методу аннотацию @GET , внутри которой находится конечная точка, на которую мы хотим отправить запрос. Как вы видите, мы не добавляем полный URL, т.к. Retrofit автоматически возьмёт BASE_URL , переданный в класс NetworkService , и добавит его к остальной части URL-адреса.

Возвращаемый тип метода называется Call<Post> . Call — это класс, предоставляемый непосредственно самой библиотекой. И все методы в интерфейсе должны возвращать значения этого типа. Это generic-класс, принимающий в себя тип объекта, который мы хотим конвертировать в JSON. Мы передали Post , т.к. это именно тот объект, в который хотим преобразовать JSON-ответ. В параметры мы передали целое число и аннотировали его с помощью @Path , внутри которого записали id . Retrofit возьмёт это значение и в конечной точке заменит на него . Таким образом, если мы передадим значение 1 в качестве параметра, то конечная точка будет выглядеть так — /posts/1 , если передадим значение 10, то конечная точка получится — /posts/10 .

Теперь нам нужно, чтобы Retrofit предоставил реализацию интерфейса JSONPlaceHolderApi . Для этого используем метод create() :

Далее нужно получить JSONPlaceHolderApi из NetworkService и отправить запрос:

Возвращённый объект Call содержит метод с именем enqueue , который принимает в качестве параметра Callback<T> . В onResponse мы получаем результат Response<Post> , содержащий возвращённый с сервера объект Post . Чтобы получаем сам объект Post , используем метод response.body() . Остальная часть кода понятна без дополнительных пояснений.

Отправка различных типов запросов

В API JSONPlaceHolder есть много разных конечных точек, которые можно использовать.

Получение списка сообщений

Для получения списка всех сообщений мы изменили конечную точку и возвращаемый тип функции.

Отправка запроса с параметром

Если вы хотите отправить запрос с параметром, то нужно всего лишь использовать аннотацию @Query() для соответствующего параметра в методе:

Поэтому если мы передадим значение 6 в параметре метода, то конечная точка будет следующей — /posts?userId=6 .

Отправка POST запроса

Для отправки POST-запроса нужно просто изменить аннотацию метода.

Чтобы сформировать тело запроса для данного метода, мы используем аннотацию @Body для передаваемого параметра. Retrofit будет использовать Gson для конвертации @Body в JSON.

Существует ещё несколько различных типов запросов, которые вы можете использовать, но это уже тема для отдельной статьи.

Перехват запросов

Retrofit предоставляет способ перехвата запросов и их логирования в Logcat. Давайте настроим перехватчик и посмотрим на эту магию. Добавьте следующую зависимость в файл build.gradle :

Обновите класс NetworkService таким образом:

Теперь, когда вы отправляете или получаете запрос, все его данные, включая URL, заголовки, тело, будут выведены в лог:

На этом наша статья заканчивается. Код для этого проекта вы можете найти на GitHub.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *